PSS-Laboratorium Test
Programowanie systemów sterowania
Wczytywanie...
Szukanie...
Brak dopasowań
json.hpp
Idź do dokumentacji tego pliku.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.2
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9/****************************************************************************\
10 * Note on documentation: The source files contain links to the online *
11 * documentation of the public API at https://json.nlohmann.me. This URL *
12 * contains the most recent documentation and should also be applicable to *
13 * previous versions; documentation for deprecated functions is not *
14 * removed, but marked deprecated. See "Generate documentation" section in *
15 * file docs/README.md. *
16\****************************************************************************/
17
18#ifndef INCLUDE_NLOHMANN_JSON_HPP_
19#define INCLUDE_NLOHMANN_JSON_HPP_
20
21#include <algorithm> // all_of, find, for_each
22#include <cstddef> // nullptr_t, ptrdiff_t, size_t
23#include <functional> // hash, less
24#include <initializer_list> // initializer_list
25#ifndef JSON_NO_IO
26#include <iosfwd> // istream, ostream
27#endif // JSON_NO_IO
28#include <iterator> // random_access_iterator_tag
29#include <memory> // unique_ptr
30#include <string> // string, stoi, to_string
31#include <utility> // declval, forward, move, pair, swap
32#include <vector> // vector
33
34// #include <nlohmann/adl_serializer.hpp>
35// __ _____ _____ _____
36// __| | __| | | | JSON for Modern C++
37// | | |__ | | | | | | version 3.11.2
38// |_____|_____|_____|_|___| https://github.com/nlohmann/json
39//
40// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
41// SPDX-License-Identifier: MIT
42
43
44
45#include <utility>
46
47// #include <nlohmann/detail/abi_macros.hpp>
48// __ _____ _____ _____
49// __| | __| | | | JSON for Modern C++
50// | | |__ | | | | | | version 3.11.2
51// |_____|_____|_____|_|___| https://github.com/nlohmann/json
52//
53// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
54// SPDX-License-Identifier: MIT
55
56
57
58// This file contains all macro definitions affecting or depending on the ABI
59
60#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
61#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
62#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2
63#warning "Already included a different version of the library!"
64#endif
65#endif
66#endif
67
68#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
69#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
70#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum)
71
72#ifndef JSON_DIAGNOSTICS
73#define JSON_DIAGNOSTICS 0
74#endif
75
76#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
77#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
78#endif
79
80#if JSON_DIAGNOSTICS
81#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
82#else
83#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
84#endif
85
86#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
87#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
88#else
89#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
90#endif
91
92#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
93#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
94#endif
95
96// Construct the namespace ABI tags component
97#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
98#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
99 NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
100
101#define NLOHMANN_JSON_ABI_TAGS \
102 NLOHMANN_JSON_ABI_TAGS_CONCAT( \
103 NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
104 NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
105
106// Construct the namespace version component
107#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
108 _v ## major ## _ ## minor ## _ ## patch
109#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
110 NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
111
112#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
113#define NLOHMANN_JSON_NAMESPACE_VERSION
114#else
115#define NLOHMANN_JSON_NAMESPACE_VERSION \
116 NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
117 NLOHMANN_JSON_VERSION_MINOR, \
118 NLOHMANN_JSON_VERSION_PATCH)
119#endif
120
121// Combine namespace components
122#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
123#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
124 NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
125
126#ifndef NLOHMANN_JSON_NAMESPACE
127#define NLOHMANN_JSON_NAMESPACE \
128 nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
129 NLOHMANN_JSON_ABI_TAGS, \
130 NLOHMANN_JSON_NAMESPACE_VERSION)
131#endif
132
133#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
134#define NLOHMANN_JSON_NAMESPACE_BEGIN \
135 namespace nlohmann \
136 { \
137 inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
138 NLOHMANN_JSON_ABI_TAGS, \
139 NLOHMANN_JSON_NAMESPACE_VERSION) \
140 {
141#endif
142
143#ifndef NLOHMANN_JSON_NAMESPACE_END
144#define NLOHMANN_JSON_NAMESPACE_END \
145 } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
146 } // namespace nlohmann
147#endif
148
149// #include <nlohmann/detail/conversions/from_json.hpp>
150// __ _____ _____ _____
151// __| | __| | | | JSON for Modern C++
152// | | |__ | | | | | | version 3.11.2
153// |_____|_____|_____|_|___| https://github.com/nlohmann/json
154//
155// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
156// SPDX-License-Identifier: MIT
157
158
159
160#include <algorithm> // transform
161#include <array> // array
162#include <forward_list> // forward_list
163#include <iterator> // inserter, front_inserter, end
164#include <map> // map
165#include <string> // string
166#include <tuple> // tuple, make_tuple
167#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
168#include <unordered_map> // unordered_map
169#include <utility> // pair, declval
170#include <valarray> // valarray
171
172// #include <nlohmann/detail/exceptions.hpp>
173// __ _____ _____ _____
174// __| | __| | | | JSON for Modern C++
175// | | |__ | | | | | | version 3.11.2
176// |_____|_____|_____|_|___| https://github.com/nlohmann/json
177//
178// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
179// SPDX-License-Identifier: MIT
180
181
182
183#include <cstddef> // nullptr_t
184#include <exception> // exception
185#if JSON_DIAGNOSTICS
186#include <numeric> // accumulate
187#endif
188#include <stdexcept> // runtime_error
189#include <string> // to_string
190#include <vector> // vector
191
192// #include <nlohmann/detail/value_t.hpp>
193// __ _____ _____ _____
194// __| | __| | | | JSON for Modern C++
195// | | |__ | | | | | | version 3.11.2
196// |_____|_____|_____|_|___| https://github.com/nlohmann/json
197//
198// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
199// SPDX-License-Identifier: MIT
200
201
202
203#include <array> // array
204#include <cstddef> // size_t
205#include <cstdint> // uint8_t
206#include <string> // string
207
208// #include <nlohmann/detail/macro_scope.hpp>
209// __ _____ _____ _____
210// __| | __| | | | JSON for Modern C++
211// | | |__ | | | | | | version 3.11.2
212// |_____|_____|_____|_|___| https://github.com/nlohmann/json
213//
214// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
215// SPDX-License-Identifier: MIT
216
217
218
219#include <utility> // declval, pair
220// #include <nlohmann/detail/meta/detected.hpp>
221// __ _____ _____ _____
222// __| | __| | | | JSON for Modern C++
223// | | |__ | | | | | | version 3.11.2
224// |_____|_____|_____|_|___| https://github.com/nlohmann/json
225//
226// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
227// SPDX-License-Identifier: MIT
228
229
230
231#include <type_traits>
232
233// #include <nlohmann/detail/meta/void_t.hpp>
234// __ _____ _____ _____
235// __| | __| | | | JSON for Modern C++
236// | | |__ | | | | | | version 3.11.2
237// |_____|_____|_____|_|___| https://github.com/nlohmann/json
238//
239// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
240// SPDX-License-Identifier: MIT
241
242
243
244// #include <nlohmann/detail/abi_macros.hpp>
245
246
248namespace detail
249{
250
251 template<typename ...Ts> struct make_void
252 {
253 using type = void;
254 };
255 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
256
257} // namespace detail
259
260
262namespace detail
263{
264
265 // https://en.cppreference.com/w/cpp/experimental/is_detected
266 struct nonesuch
267 {
268 nonesuch() = delete;
269 ~nonesuch() = delete;
270 nonesuch(nonesuch const&) = delete;
271 nonesuch(nonesuch const&&) = delete;
272 void operator=(nonesuch const&) = delete;
273 void operator=(nonesuch&&) = delete;
274 };
275
276 template<class Default,
277 class AlwaysVoid,
278 template<class...> class Op,
279 class... Args>
280 struct detector
281 {
282 using value_t = std::false_type;
283 using type = Default;
284 };
285
286 template<class Default, template<class...> class Op, class... Args>
287 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
288 {
289 using value_t = std::true_type;
290 using type = Op<Args...>;
291 };
292
293 template<template<class...> class Op, class... Args>
294 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
295
296 template<template<class...> class Op, class... Args>
297 struct is_detected_lazy : is_detected<Op, Args...> { };
298
299 template<template<class...> class Op, class... Args>
300 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
301
302 template<class Default, template<class...> class Op, class... Args>
303 using detected_or = detector<Default, void, Op, Args...>;
304
305 template<class Default, template<class...> class Op, class... Args>
306 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
307
308 template<class Expected, template<class...> class Op, class... Args>
309 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
310
311 template<class To, template<class...> class Op, class... Args>
313 std::is_convertible<detected_t<Op, Args...>, To>;
314
315} // namespace detail
317
318// #include <nlohmann/thirdparty/hedley/hedley.hpp>
319
320
321// __ _____ _____ _____
322// __| | __| | | | JSON for Modern C++
323// | | |__ | | | | | | version 3.11.2
324// |_____|_____|_____|_|___| https://github.com/nlohmann/json
325//
326// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
327// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
328// SPDX-License-Identifier: MIT
329
330/* Hedley - https://nemequ.github.io/hedley
331 * Created by Evan Nemerson <evan@nemerson.com>
332 */
333
334#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
335#if defined(JSON_HEDLEY_VERSION)
336#undef JSON_HEDLEY_VERSION
337#endif
338#define JSON_HEDLEY_VERSION 15
339
340#if defined(JSON_HEDLEY_STRINGIFY_EX)
341#undef JSON_HEDLEY_STRINGIFY_EX
342#endif
343#define JSON_HEDLEY_STRINGIFY_EX(x) #x
344
345#if defined(JSON_HEDLEY_STRINGIFY)
346#undef JSON_HEDLEY_STRINGIFY
347#endif
348#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
349
350#if defined(JSON_HEDLEY_CONCAT_EX)
351#undef JSON_HEDLEY_CONCAT_EX
352#endif
353#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
354
355#if defined(JSON_HEDLEY_CONCAT)
356#undef JSON_HEDLEY_CONCAT
357#endif
358#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
359
360#if defined(JSON_HEDLEY_CONCAT3_EX)
361#undef JSON_HEDLEY_CONCAT3_EX
362#endif
363#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
364
365#if defined(JSON_HEDLEY_CONCAT3)
366#undef JSON_HEDLEY_CONCAT3
367#endif
368#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
369
370#if defined(JSON_HEDLEY_VERSION_ENCODE)
371#undef JSON_HEDLEY_VERSION_ENCODE
372#endif
373#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
374
375#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
376#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
377#endif
378#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
379
380#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
381#undef JSON_HEDLEY_VERSION_DECODE_MINOR
382#endif
383#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
384
385#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
386#undef JSON_HEDLEY_VERSION_DECODE_REVISION
387#endif
388#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
389
390#if defined(JSON_HEDLEY_GNUC_VERSION)
391#undef JSON_HEDLEY_GNUC_VERSION
392#endif
393#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
394#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
395#elif defined(__GNUC__)
396#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
397#endif
398
399#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
400#undef JSON_HEDLEY_GNUC_VERSION_CHECK
401#endif
402#if defined(JSON_HEDLEY_GNUC_VERSION)
403#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
404#else
405#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
406#endif
407
408#if defined(JSON_HEDLEY_MSVC_VERSION)
409#undef JSON_HEDLEY_MSVC_VERSION
410#endif
411#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
412#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
413#elif defined(_MSC_FULL_VER) && !defined(__ICL)
414#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
415#elif defined(_MSC_VER) && !defined(__ICL)
416#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
417#endif
418
419#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
420#undef JSON_HEDLEY_MSVC_VERSION_CHECK
421#endif
422#if !defined(JSON_HEDLEY_MSVC_VERSION)
423#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
424#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
425#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
426#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
427#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
428#else
429#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
430#endif
431
432#if defined(JSON_HEDLEY_INTEL_VERSION)
433#undef JSON_HEDLEY_INTEL_VERSION
434#endif
435#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
436#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
437#elif defined(__INTEL_COMPILER) && !defined(__ICL)
438#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
439#endif
440
441#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
442#undef JSON_HEDLEY_INTEL_VERSION_CHECK
443#endif
444#if defined(JSON_HEDLEY_INTEL_VERSION)
445#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446#else
447#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
448#endif
449
450#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
451#undef JSON_HEDLEY_INTEL_CL_VERSION
452#endif
453#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
454#define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
455#endif
456
457#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
458#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
459#endif
460#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
461#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462#else
463#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
464#endif
465
466#if defined(JSON_HEDLEY_PGI_VERSION)
467#undef JSON_HEDLEY_PGI_VERSION
468#endif
469#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
470#define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
471#endif
472
473#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
474#undef JSON_HEDLEY_PGI_VERSION_CHECK
475#endif
476#if defined(JSON_HEDLEY_PGI_VERSION)
477#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478#else
479#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
480#endif
481
482#if defined(JSON_HEDLEY_SUNPRO_VERSION)
483#undef JSON_HEDLEY_SUNPRO_VERSION
484#endif
485#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
486#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
487#elif defined(__SUNPRO_C)
488#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
489#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
490#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
491#elif defined(__SUNPRO_CC)
492#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
493#endif
494
495#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
496#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
497#endif
498#if defined(JSON_HEDLEY_SUNPRO_VERSION)
499#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
500#else
501#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
502#endif
503
504#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
505#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
506#endif
507#if defined(__EMSCRIPTEN__)
508#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
509#endif
510
511#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
512#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
513#endif
514#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
515#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
516#else
517#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
518#endif
519
520#if defined(JSON_HEDLEY_ARM_VERSION)
521#undef JSON_HEDLEY_ARM_VERSION
522#endif
523#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
524#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
525#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
526#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
527#endif
528
529#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
530#undef JSON_HEDLEY_ARM_VERSION_CHECK
531#endif
532#if defined(JSON_HEDLEY_ARM_VERSION)
533#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534#else
535#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
536#endif
537
538#if defined(JSON_HEDLEY_IBM_VERSION)
539#undef JSON_HEDLEY_IBM_VERSION
540#endif
541#if defined(__ibmxl__)
542#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
543#elif defined(__xlC__) && defined(__xlC_ver__)
544#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
545#elif defined(__xlC__)
546#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
547#endif
548
549#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
550#undef JSON_HEDLEY_IBM_VERSION_CHECK
551#endif
552#if defined(JSON_HEDLEY_IBM_VERSION)
553#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
554#else
555#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
556#endif
557
558#if defined(JSON_HEDLEY_TI_VERSION)
559#undef JSON_HEDLEY_TI_VERSION
560#endif
561#if \
562 defined(__TI_COMPILER_VERSION__) && \
563 ( \
564 defined(__TMS470__) || defined(__TI_ARM__) || \
565 defined(__MSP430__) || \
566 defined(__TMS320C2000__) \
567 )
568#if (__TI_COMPILER_VERSION__ >= 16000000)
569#define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
570#endif
571#endif
572
573#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
574#undef JSON_HEDLEY_TI_VERSION_CHECK
575#endif
576#if defined(JSON_HEDLEY_TI_VERSION)
577#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
578#else
579#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
580#endif
581
582#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
583#undef JSON_HEDLEY_TI_CL2000_VERSION
584#endif
585#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
586#define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
587#endif
588
589#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
590#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
591#endif
592#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
593#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
594#else
595#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
596#endif
597
598#if defined(JSON_HEDLEY_TI_CL430_VERSION)
599#undef JSON_HEDLEY_TI_CL430_VERSION
600#endif
601#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
602#define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
603#endif
604
605#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
606#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
607#endif
608#if defined(JSON_HEDLEY_TI_CL430_VERSION)
609#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
610#else
611#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
612#endif
613
614#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
615#undef JSON_HEDLEY_TI_ARMCL_VERSION
616#endif
617#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
618#define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
619#endif
620
621#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
622#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
623#endif
624#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
625#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
626#else
627#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
628#endif
629
630#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
631#undef JSON_HEDLEY_TI_CL6X_VERSION
632#endif
633#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
634#define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
635#endif
636
637#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
638#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
639#endif
640#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
641#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
642#else
643#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
644#endif
645
646#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
647#undef JSON_HEDLEY_TI_CL7X_VERSION
648#endif
649#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
650#define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
651#endif
652
653#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
654#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
655#endif
656#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
657#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
658#else
659#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
660#endif
661
662#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
663#undef JSON_HEDLEY_TI_CLPRU_VERSION
664#endif
665#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
666#define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
667#endif
668
669#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
670#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
671#endif
672#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
673#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
674#else
675#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
676#endif
677
678#if defined(JSON_HEDLEY_CRAY_VERSION)
679#undef JSON_HEDLEY_CRAY_VERSION
680#endif
681#if defined(_CRAYC)
682#if defined(_RELEASE_PATCHLEVEL)
683#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
684#else
685#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
686#endif
687#endif
688
689#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
690#undef JSON_HEDLEY_CRAY_VERSION_CHECK
691#endif
692#if defined(JSON_HEDLEY_CRAY_VERSION)
693#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
694#else
695#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
696#endif
697
698#if defined(JSON_HEDLEY_IAR_VERSION)
699#undef JSON_HEDLEY_IAR_VERSION
700#endif
701#if defined(__IAR_SYSTEMS_ICC__)
702#if __VER__ > 1000
703#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
704#else
705#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
706#endif
707#endif
708
709#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
710#undef JSON_HEDLEY_IAR_VERSION_CHECK
711#endif
712#if defined(JSON_HEDLEY_IAR_VERSION)
713#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
714#else
715#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
716#endif
717
718#if defined(JSON_HEDLEY_TINYC_VERSION)
719#undef JSON_HEDLEY_TINYC_VERSION
720#endif
721#if defined(__TINYC__)
722#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
723#endif
724
725#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
726#undef JSON_HEDLEY_TINYC_VERSION_CHECK
727#endif
728#if defined(JSON_HEDLEY_TINYC_VERSION)
729#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
730#else
731#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
732#endif
733
734#if defined(JSON_HEDLEY_DMC_VERSION)
735#undef JSON_HEDLEY_DMC_VERSION
736#endif
737#if defined(__DMC__)
738#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
739#endif
740
741#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
742#undef JSON_HEDLEY_DMC_VERSION_CHECK
743#endif
744#if defined(JSON_HEDLEY_DMC_VERSION)
745#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
746#else
747#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
748#endif
749
750#if defined(JSON_HEDLEY_COMPCERT_VERSION)
751#undef JSON_HEDLEY_COMPCERT_VERSION
752#endif
753#if defined(__COMPCERT_VERSION__)
754#define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
755#endif
756
757#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
758#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
759#endif
760#if defined(JSON_HEDLEY_COMPCERT_VERSION)
761#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
762#else
763#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
764#endif
765
766#if defined(JSON_HEDLEY_PELLES_VERSION)
767#undef JSON_HEDLEY_PELLES_VERSION
768#endif
769#if defined(__POCC__)
770#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
771#endif
772
773#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
774#undef JSON_HEDLEY_PELLES_VERSION_CHECK
775#endif
776#if defined(JSON_HEDLEY_PELLES_VERSION)
777#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
778#else
779#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
780#endif
781
782#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
783#undef JSON_HEDLEY_MCST_LCC_VERSION
784#endif
785#if defined(__LCC__) && defined(__LCC_MINOR__)
786#define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
787#endif
788
789#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
790#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
791#endif
792#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
793#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
794#else
795#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
796#endif
797
798#if defined(JSON_HEDLEY_GCC_VERSION)
799#undef JSON_HEDLEY_GCC_VERSION
800#endif
801#if \
802 defined(JSON_HEDLEY_GNUC_VERSION) && \
803 !defined(__clang__) && \
804 !defined(JSON_HEDLEY_INTEL_VERSION) && \
805 !defined(JSON_HEDLEY_PGI_VERSION) && \
806 !defined(JSON_HEDLEY_ARM_VERSION) && \
807 !defined(JSON_HEDLEY_CRAY_VERSION) && \
808 !defined(JSON_HEDLEY_TI_VERSION) && \
809 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
810 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
811 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
812 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
813 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
814 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
815 !defined(__COMPCERT__) && \
816 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
817#define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
818#endif
819
820#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
821#undef JSON_HEDLEY_GCC_VERSION_CHECK
822#endif
823#if defined(JSON_HEDLEY_GCC_VERSION)
824#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
825#else
826#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
827#endif
828
829#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
830#undef JSON_HEDLEY_HAS_ATTRIBUTE
831#endif
832#if \
833 defined(__has_attribute) && \
834 ( \
835 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
836 )
837# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
838#else
839# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
840#endif
841
842#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
843#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
844#endif
845#if defined(__has_attribute)
846#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
847#else
848#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
849#endif
850
851#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
852#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
853#endif
854#if defined(__has_attribute)
855#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
856#else
857#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
858#endif
859
860#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
861#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
862#endif
863#if \
864 defined(__has_cpp_attribute) && \
865 defined(__cplusplus) && \
866 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
867#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
868#else
869#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
870#endif
871
872#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
873#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
874#endif
875#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
876#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
877#elif \
878 !defined(JSON_HEDLEY_PGI_VERSION) && \
879 !defined(JSON_HEDLEY_IAR_VERSION) && \
880 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
881 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
882#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
883#else
884#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
885#endif
886
887#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
888#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
889#endif
890#if defined(__has_cpp_attribute) && defined(__cplusplus)
891#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
892#else
893#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
894#endif
895
896#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
897#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
898#endif
899#if defined(__has_cpp_attribute) && defined(__cplusplus)
900#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
901#else
902#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
903#endif
904
905#if defined(JSON_HEDLEY_HAS_BUILTIN)
906#undef JSON_HEDLEY_HAS_BUILTIN
907#endif
908#if defined(__has_builtin)
909#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
910#else
911#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
912#endif
913
914#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
915#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
916#endif
917#if defined(__has_builtin)
918#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
919#else
920#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
921#endif
922
923#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
924#undef JSON_HEDLEY_GCC_HAS_BUILTIN
925#endif
926#if defined(__has_builtin)
927#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
928#else
929#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
930#endif
931
932#if defined(JSON_HEDLEY_HAS_FEATURE)
933#undef JSON_HEDLEY_HAS_FEATURE
934#endif
935#if defined(__has_feature)
936#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
937#else
938#define JSON_HEDLEY_HAS_FEATURE(feature) (0)
939#endif
940
941#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
942#undef JSON_HEDLEY_GNUC_HAS_FEATURE
943#endif
944#if defined(__has_feature)
945#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
946#else
947#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
948#endif
949
950#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
951#undef JSON_HEDLEY_GCC_HAS_FEATURE
952#endif
953#if defined(__has_feature)
954#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
955#else
956#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
957#endif
958
959#if defined(JSON_HEDLEY_HAS_EXTENSION)
960#undef JSON_HEDLEY_HAS_EXTENSION
961#endif
962#if defined(__has_extension)
963#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
964#else
965#define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
966#endif
967
968#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
969#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
970#endif
971#if defined(__has_extension)
972#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
973#else
974#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
975#endif
976
977#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
978#undef JSON_HEDLEY_GCC_HAS_EXTENSION
979#endif
980#if defined(__has_extension)
981#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
982#else
983#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
984#endif
985
986#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
987#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
988#endif
989#if defined(__has_declspec_attribute)
990#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
991#else
992#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
993#endif
994
995#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
996#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
997#endif
998#if defined(__has_declspec_attribute)
999#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1000#else
1001#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1002#endif
1003
1004#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1005#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1006#endif
1007#if defined(__has_declspec_attribute)
1008#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1009#else
1010#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1011#endif
1012
1013#if defined(JSON_HEDLEY_HAS_WARNING)
1014#undef JSON_HEDLEY_HAS_WARNING
1015#endif
1016#if defined(__has_warning)
1017#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1018#else
1019#define JSON_HEDLEY_HAS_WARNING(warning) (0)
1020#endif
1021
1022#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1023#undef JSON_HEDLEY_GNUC_HAS_WARNING
1024#endif
1025#if defined(__has_warning)
1026#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1027#else
1028#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1029#endif
1030
1031#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1032#undef JSON_HEDLEY_GCC_HAS_WARNING
1033#endif
1034#if defined(__has_warning)
1035#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1036#else
1037#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1038#endif
1039
1040#if \
1041 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1042 defined(__clang__) || \
1043 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1044 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1045 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1046 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1047 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1048 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1049 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1050 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1051 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1052 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1053 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1054 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1055 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1056 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1057 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1058 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1059#define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1060#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1061#define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1062#else
1063#define JSON_HEDLEY_PRAGMA(value)
1064#endif
1065
1066#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1067#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1068#endif
1069#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1070#undef JSON_HEDLEY_DIAGNOSTIC_POP
1071#endif
1072#if defined(__clang__)
1073#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1074#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1075#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1076#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1077#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1078#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1079#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1080#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1081#elif \
1082 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1083 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1084#define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1085#define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1086#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1087#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1088#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1089#elif \
1090 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1091 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1092 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1093 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1094 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1095 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1096#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1097#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1098#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1099#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1100#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1101#else
1102#define JSON_HEDLEY_DIAGNOSTIC_PUSH
1103#define JSON_HEDLEY_DIAGNOSTIC_POP
1104#endif
1105
1106 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1107 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1108#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1109#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1110#endif
1111#if defined(__cplusplus)
1112# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1113# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1114# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1115# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1116 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1117 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1118 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1119 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1120 xpr \
1121 JSON_HEDLEY_DIAGNOSTIC_POP
1122# else
1123# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1124 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1125 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1126 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1127 xpr \
1128 JSON_HEDLEY_DIAGNOSTIC_POP
1129# endif
1130# else
1131# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1132 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1133 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1134 xpr \
1135 JSON_HEDLEY_DIAGNOSTIC_POP
1136# endif
1137# endif
1138#endif
1139#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1140#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1141#endif
1142
1143#if defined(JSON_HEDLEY_CONST_CAST)
1144#undef JSON_HEDLEY_CONST_CAST
1145#endif
1146#if defined(__cplusplus)
1147# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1148#elif \
1149 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1150 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1151 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1152# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1153 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1154 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1155 ((T) (expr)); \
1156 JSON_HEDLEY_DIAGNOSTIC_POP \
1157 }))
1158#else
1159# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1160#endif
1161
1162#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1163#undef JSON_HEDLEY_REINTERPRET_CAST
1164#endif
1165#if defined(__cplusplus)
1166#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1167#else
1168#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1169#endif
1170
1171#if defined(JSON_HEDLEY_STATIC_CAST)
1172#undef JSON_HEDLEY_STATIC_CAST
1173#endif
1174#if defined(__cplusplus)
1175#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1176#else
1177#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1178#endif
1179
1180#if defined(JSON_HEDLEY_CPP_CAST)
1181#undef JSON_HEDLEY_CPP_CAST
1182#endif
1183#if defined(__cplusplus)
1184# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1185# define JSON_HEDLEY_CPP_CAST(T, expr) \
1186 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1187 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1188 ((T) (expr)) \
1189 JSON_HEDLEY_DIAGNOSTIC_POP
1190# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1191# define JSON_HEDLEY_CPP_CAST(T, expr) \
1192 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1193 _Pragma("diag_suppress=Pe137") \
1194 JSON_HEDLEY_DIAGNOSTIC_POP
1195# else
1196# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1197# endif
1198#else
1199# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1200#endif
1201
1202#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1203#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1204#endif
1205#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1206#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1207#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1208#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1209#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1210#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1211#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1212#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1213#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1214#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1215#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1216#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1217#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1218#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1219#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1220#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1221#elif \
1222 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1233#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1234#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1235#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1236#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1237#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1238#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1239#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1240#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1241#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1242#else
1243#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1244#endif
1245
1246#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1247#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1248#endif
1249#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1250#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1251#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1252#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1253#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1254#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1255#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1256#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1257#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1258#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1259#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1260#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1261#elif \
1262 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1263 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1264 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1265 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1266#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1267#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1268#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1269#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1270#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1271#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1272#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1273#else
1274#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1275#endif
1276
1277#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1278#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1279#endif
1280#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1281#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1282#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1283#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1284#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1285#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1286#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1287#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1288#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1289#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1290#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1291#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1292#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1293#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1294#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1295#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1296#elif \
1297 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1298 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1299 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1300#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1301#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1302#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1303#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1304#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1305#else
1306#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1307#endif
1308
1309#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1310#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1311#endif
1312#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1313#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1314#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1315#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1316#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1317#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1318#else
1319#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1320#endif
1321
1322#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1323#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1324#endif
1325#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1326#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1327#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1328#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1329#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1330#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1331#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1332#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1333#else
1334#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1335#endif
1336
1337#if defined(JSON_HEDLEY_DEPRECATED)
1338#undef JSON_HEDLEY_DEPRECATED
1339#endif
1340#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1341#undef JSON_HEDLEY_DEPRECATED_FOR
1342#endif
1343#if \
1344 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1345 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1346#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1347#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1348#elif \
1349 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1350 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1351 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1352 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1353 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1354 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1355 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1356 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1357 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1358 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1359 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1360 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1361#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1362#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1363#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1364#define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1365#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1366#elif \
1367 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1368 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1369 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1370 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1371 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1372 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1373 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1374 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1375 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1376 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1377 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1378 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1379 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1380 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1381 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1382 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1383#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1384#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1385#elif \
1386 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1387 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1388 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1389#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1390#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1391#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1392#define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1393#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1394#else
1395#define JSON_HEDLEY_DEPRECATED(since)
1396#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1397#endif
1398
1399#if defined(JSON_HEDLEY_UNAVAILABLE)
1400#undef JSON_HEDLEY_UNAVAILABLE
1401#endif
1402#if \
1403 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1404 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1405 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1406 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1407#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1408#else
1409#define JSON_HEDLEY_UNAVAILABLE(available_since)
1410#endif
1411
1412#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1413#undef JSON_HEDLEY_WARN_UNUSED_RESULT
1414#endif
1415#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1416#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1417#endif
1418#if \
1419 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1420 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1421 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1422 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1423 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1424 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1425 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1426 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1427 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1428 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1429 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1430 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1431 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1432 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1433 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1434 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1435 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1436#define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1437#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1438#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1439#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1440#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1441#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1442#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1443#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1444#elif defined(_Check_return_) /* SAL */
1445#define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1446#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1447#else
1448#define JSON_HEDLEY_WARN_UNUSED_RESULT
1449#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1450#endif
1451
1452#if defined(JSON_HEDLEY_SENTINEL)
1453#undef JSON_HEDLEY_SENTINEL
1454#endif
1455#if \
1456 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1457 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1458 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1459 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1460 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1461#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1462#else
1463#define JSON_HEDLEY_SENTINEL(position)
1464#endif
1465
1466#if defined(JSON_HEDLEY_NO_RETURN)
1467#undef JSON_HEDLEY_NO_RETURN
1468#endif
1469#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1470#define JSON_HEDLEY_NO_RETURN __noreturn
1471#elif \
1472 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1474#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1475#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1476#define JSON_HEDLEY_NO_RETURN _Noreturn
1477#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1478#define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1479#elif \
1480 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1481 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1482 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1483 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1484 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1485 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1486 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1488 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1490 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1492 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1493 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1494 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1495 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1496 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1497#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1498#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1499#define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1500#elif \
1501 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1502 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1503#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1504#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1505#define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1506#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1507#define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1508#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1509#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1510#else
1511#define JSON_HEDLEY_NO_RETURN
1512#endif
1513
1514#if defined(JSON_HEDLEY_NO_ESCAPE)
1515#undef JSON_HEDLEY_NO_ESCAPE
1516#endif
1517#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1518#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1519#else
1520#define JSON_HEDLEY_NO_ESCAPE
1521#endif
1522
1523#if defined(JSON_HEDLEY_UNREACHABLE)
1524#undef JSON_HEDLEY_UNREACHABLE
1525#endif
1526#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1527#undef JSON_HEDLEY_UNREACHABLE_RETURN
1528#endif
1529#if defined(JSON_HEDLEY_ASSUME)
1530#undef JSON_HEDLEY_ASSUME
1531#endif
1532#if \
1533 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1534 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1535 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1536#define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1537#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1538#define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1539#elif \
1540 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1541 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1542#if defined(__cplusplus)
1543#define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1544#else
1545#define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1546#endif
1547#endif
1548#if \
1549 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1550 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1551 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1552 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1553 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1554 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1555 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1556#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1557#elif defined(JSON_HEDLEY_ASSUME)
1558#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1559#endif
1560#if !defined(JSON_HEDLEY_ASSUME)
1561#if defined(JSON_HEDLEY_UNREACHABLE)
1562#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1563#else
1564#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1565#endif
1566#endif
1567#if defined(JSON_HEDLEY_UNREACHABLE)
1568#if \
1569 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1570 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1571#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1572#else
1573#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1574#endif
1575#else
1576#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1577#endif
1578#if !defined(JSON_HEDLEY_UNREACHABLE)
1579#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1580#endif
1581
1583#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1584#pragma clang diagnostic ignored "-Wpedantic"
1585#endif
1586#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1587#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1588#endif
1589#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1590#if defined(__clang__)
1591#pragma clang diagnostic ignored "-Wvariadic-macros"
1592#elif defined(JSON_HEDLEY_GCC_VERSION)
1593#pragma GCC diagnostic ignored "-Wvariadic-macros"
1594#endif
1595#endif
1596#if defined(JSON_HEDLEY_NON_NULL)
1597#undef JSON_HEDLEY_NON_NULL
1598#endif
1599#if \
1600 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1601 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1602 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1603 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1604#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1605#else
1606#define JSON_HEDLEY_NON_NULL(...)
1607#endif
1609
1610#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1611#undef JSON_HEDLEY_PRINTF_FORMAT
1612#endif
1613#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1614#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1615#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1616#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1617#elif \
1618 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1619 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1620 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1621 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1622 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1623 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1624 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1625 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1626 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1627 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1628 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1629 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1630 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1631 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1632 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1633 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1634 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1635#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1636#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1637#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1638#else
1639#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1640#endif
1641
1642#if defined(JSON_HEDLEY_CONSTEXPR)
1643#undef JSON_HEDLEY_CONSTEXPR
1644#endif
1645#if defined(__cplusplus)
1646#if __cplusplus >= 201103L
1647#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1648#endif
1649#endif
1650#if !defined(JSON_HEDLEY_CONSTEXPR)
1651#define JSON_HEDLEY_CONSTEXPR
1652#endif
1653
1654#if defined(JSON_HEDLEY_PREDICT)
1655#undef JSON_HEDLEY_PREDICT
1656#endif
1657#if defined(JSON_HEDLEY_LIKELY)
1658#undef JSON_HEDLEY_LIKELY
1659#endif
1660#if defined(JSON_HEDLEY_UNLIKELY)
1661#undef JSON_HEDLEY_UNLIKELY
1662#endif
1663#if defined(JSON_HEDLEY_UNPREDICTABLE)
1664#undef JSON_HEDLEY_UNPREDICTABLE
1665#endif
1666#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1667#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1668#endif
1669#if \
1670 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1671 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1672 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1673# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1674# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1675# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1676# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1677# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1678#elif \
1679 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1680 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1681 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1683 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1686 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1687 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1688 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1689 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1690 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1691 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1692 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1693 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1694 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1695# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1696 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1697# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1698 (__extension__ ({ \
1699 double hedley_probability_ = (probability); \
1700 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1701 }))
1702# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1703 (__extension__ ({ \
1704 double hedley_probability_ = (probability); \
1705 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1706 }))
1707# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1708# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1709#else
1710# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1711# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1712# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1713# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1714# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1715#endif
1716#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1717#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1718#endif
1719
1720#if defined(JSON_HEDLEY_MALLOC)
1721#undef JSON_HEDLEY_MALLOC
1722#endif
1723#if \
1724 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1725 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1726 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1727 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1728 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1729 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1730 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1731 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1732 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1733 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1734 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1735 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1736 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1737 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1738 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1739 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1740 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1741 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1742#define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1743#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1744#define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1745#elif \
1746 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1747 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1748#define JSON_HEDLEY_MALLOC __declspec(restrict)
1749#else
1750#define JSON_HEDLEY_MALLOC
1751#endif
1752
1753#if defined(JSON_HEDLEY_PURE)
1754#undef JSON_HEDLEY_PURE
1755#endif
1756#if \
1757 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1758 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1759 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1760 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1761 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1762 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1763 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1764 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1765 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1766 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1767 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1768 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1769 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1770 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1771 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1772 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1773 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1774 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1775 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1776# define JSON_HEDLEY_PURE __attribute__((__pure__))
1777#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1778# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1779#elif defined(__cplusplus) && \
1780 ( \
1781 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1782 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1783 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1784 )
1785# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1786#else
1787# define JSON_HEDLEY_PURE
1788#endif
1789
1790#if defined(JSON_HEDLEY_CONST)
1791#undef JSON_HEDLEY_CONST
1792#endif
1793#if \
1794 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1795 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1796 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1797 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1798 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1799 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1800 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1801 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1802 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1803 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1804 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1805 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1806 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1807 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1808 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1809 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1810 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1811 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1812 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1813#define JSON_HEDLEY_CONST __attribute__((__const__))
1814#elif \
1815 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1816#define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1817#else
1818#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1819#endif
1820
1821#if defined(JSON_HEDLEY_RESTRICT)
1822#undef JSON_HEDLEY_RESTRICT
1823#endif
1824#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1825#define JSON_HEDLEY_RESTRICT restrict
1826#elif \
1827 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1828 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1829 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1830 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1831 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1832 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1833 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1834 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1835 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1836 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1837 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1838 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1839 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1840 defined(__clang__) || \
1841 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1842#define JSON_HEDLEY_RESTRICT __restrict
1843#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1844#define JSON_HEDLEY_RESTRICT _Restrict
1845#else
1846#define JSON_HEDLEY_RESTRICT
1847#endif
1848
1849#if defined(JSON_HEDLEY_INLINE)
1850#undef JSON_HEDLEY_INLINE
1851#endif
1852#if \
1853 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1854 (defined(__cplusplus) && (__cplusplus >= 199711L))
1855#define JSON_HEDLEY_INLINE inline
1856#elif \
1857 defined(JSON_HEDLEY_GCC_VERSION) || \
1858 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1859#define JSON_HEDLEY_INLINE __inline__
1860#elif \
1861 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1862 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1863 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1864 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1865 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1866 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1867 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1868 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1869 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1870 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1871#define JSON_HEDLEY_INLINE __inline
1872#else
1873#define JSON_HEDLEY_INLINE
1874#endif
1875
1876#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1877#undef JSON_HEDLEY_ALWAYS_INLINE
1878#endif
1879#if \
1880 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1881 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1882 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1883 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1884 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1885 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1886 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1887 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1888 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1889 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1890 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1891 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1892 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1893 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1894 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1895 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1896 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1897 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1898 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1899# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1900#elif \
1901 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1902 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1903# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1904#elif defined(__cplusplus) && \
1905 ( \
1906 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1907 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1908 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1909 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1910 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1911 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1912 )
1913# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1914#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1915# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1916#else
1917# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1918#endif
1919
1920#if defined(JSON_HEDLEY_NEVER_INLINE)
1921#undef JSON_HEDLEY_NEVER_INLINE
1922#endif
1923#if \
1924 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1925 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1926 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1927 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1928 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1929 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1930 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1931 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1932 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1933 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1934 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1935 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1936 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1937 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1938 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1939 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1940 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1941 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1942 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1943#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1944#elif \
1945 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1946 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1947#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1948#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1949#define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1950#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1951#define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1952#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1953#define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1954#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1955#define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1956#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1957#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1958#else
1959#define JSON_HEDLEY_NEVER_INLINE
1960#endif
1961
1962#if defined(JSON_HEDLEY_PRIVATE)
1963#undef JSON_HEDLEY_PRIVATE
1964#endif
1965#if defined(JSON_HEDLEY_PUBLIC)
1966#undef JSON_HEDLEY_PUBLIC
1967#endif
1968#if defined(JSON_HEDLEY_IMPORT)
1969#undef JSON_HEDLEY_IMPORT
1970#endif
1971#if defined(_WIN32) || defined(__CYGWIN__)
1972# define JSON_HEDLEY_PRIVATE
1973# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1974# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1975#else
1976# if \
1977 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1978 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1979 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1980 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1981 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1982 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1983 ( \
1984 defined(__TI_EABI__) && \
1985 ( \
1986 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1987 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1988 ) \
1989 ) || \
1990 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1991# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1992# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1993# else
1994# define JSON_HEDLEY_PRIVATE
1995# define JSON_HEDLEY_PUBLIC
1996# endif
1997# define JSON_HEDLEY_IMPORT extern
1998#endif
1999
2000#if defined(JSON_HEDLEY_NO_THROW)
2001#undef JSON_HEDLEY_NO_THROW
2002#endif
2003#if \
2004 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2005 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2006 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2007 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2008#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2009#elif \
2010 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2011 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2012 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2013#define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2014#else
2015#define JSON_HEDLEY_NO_THROW
2016#endif
2017
2018#if defined(JSON_HEDLEY_FALL_THROUGH)
2019#undef JSON_HEDLEY_FALL_THROUGH
2020#endif
2021#if \
2022 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2023 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2024 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2025#define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2026#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2027#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2028#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2029#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2030#elif defined(__fallthrough) /* SAL */
2031#define JSON_HEDLEY_FALL_THROUGH __fallthrough
2032#else
2033#define JSON_HEDLEY_FALL_THROUGH
2034#endif
2035
2036#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2037#undef JSON_HEDLEY_RETURNS_NON_NULL
2038#endif
2039#if \
2040 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2041 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2042 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2043#define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2044#elif defined(_Ret_notnull_) /* SAL */
2045#define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2046#else
2047#define JSON_HEDLEY_RETURNS_NON_NULL
2048#endif
2049
2050#if defined(JSON_HEDLEY_ARRAY_PARAM)
2051#undef JSON_HEDLEY_ARRAY_PARAM
2052#endif
2053#if \
2054 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2055 !defined(__STDC_NO_VLA__) && \
2056 !defined(__cplusplus) && \
2057 !defined(JSON_HEDLEY_PGI_VERSION) && \
2058 !defined(JSON_HEDLEY_TINYC_VERSION)
2059#define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2060#else
2061#define JSON_HEDLEY_ARRAY_PARAM(name)
2062#endif
2063
2064#if defined(JSON_HEDLEY_IS_CONSTANT)
2065#undef JSON_HEDLEY_IS_CONSTANT
2066#endif
2067#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2068#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2069#endif
2070 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
2071 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2072#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2073#undef JSON_HEDLEY_IS_CONSTEXPR_
2074#endif
2075#if \
2076 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2077 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2078 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2079 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2080 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2081 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2082 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2083 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2084 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2085 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2086#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2087#endif
2088#if !defined(__cplusplus)
2089# if \
2090 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2091 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2092 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2093 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2094 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2095 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2096 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2097#if defined(__INTPTR_TYPE__)
2098#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2099#else
2100#include <stdint.h>
2101#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2102#endif
2103# elif \
2104 ( \
2105 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2106 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2107 !defined(JSON_HEDLEY_PGI_VERSION) && \
2108 !defined(JSON_HEDLEY_IAR_VERSION)) || \
2109 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2110 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2111 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2112 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2113 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2114#if defined(__INTPTR_TYPE__)
2115#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2116#else
2117#include <stdint.h>
2118#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2119#endif
2120# elif \
2121 defined(JSON_HEDLEY_GCC_VERSION) || \
2122 defined(JSON_HEDLEY_INTEL_VERSION) || \
2123 defined(JSON_HEDLEY_TINYC_VERSION) || \
2124 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2125 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2126 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2127 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2128 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2129 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2130 defined(__clang__)
2131# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2132 sizeof(void) != \
2133 sizeof(*( \
2134 1 ? \
2135 ((void*) ((expr) * 0L) ) : \
2136((struct { char v[sizeof(void) * 2]; } *) 1) \
2137 ) \
2138 ) \
2139 )
2140# endif
2141#endif
2142#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2143#if !defined(JSON_HEDLEY_IS_CONSTANT)
2144#define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2145#endif
2146#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2147#else
2148#if !defined(JSON_HEDLEY_IS_CONSTANT)
2149#define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2150#endif
2151#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2152#endif
2153
2154#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2155#undef JSON_HEDLEY_BEGIN_C_DECLS
2156#endif
2157#if defined(JSON_HEDLEY_END_C_DECLS)
2158#undef JSON_HEDLEY_END_C_DECLS
2159#endif
2160#if defined(JSON_HEDLEY_C_DECL)
2161#undef JSON_HEDLEY_C_DECL
2162#endif
2163#if defined(__cplusplus)
2164#define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2165#define JSON_HEDLEY_END_C_DECLS }
2166#define JSON_HEDLEY_C_DECL extern "C"
2167#else
2168#define JSON_HEDLEY_BEGIN_C_DECLS
2169#define JSON_HEDLEY_END_C_DECLS
2170#define JSON_HEDLEY_C_DECL
2171#endif
2172
2173#if defined(JSON_HEDLEY_STATIC_ASSERT)
2174#undef JSON_HEDLEY_STATIC_ASSERT
2175#endif
2176#if \
2177 !defined(__cplusplus) && ( \
2178 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2179 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2180 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2181 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2182 defined(_Static_assert) \
2183 )
2184# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2185#elif \
2186 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2187 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2188 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2189# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2190#else
2191# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2192#endif
2193
2194#if defined(JSON_HEDLEY_NULL)
2195#undef JSON_HEDLEY_NULL
2196#endif
2197#if defined(__cplusplus)
2198#if __cplusplus >= 201103L
2199#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2200#elif defined(NULL)
2201#define JSON_HEDLEY_NULL NULL
2202#else
2203#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2204#endif
2205#elif defined(NULL)
2206#define JSON_HEDLEY_NULL NULL
2207#else
2208#define JSON_HEDLEY_NULL ((void*) 0)
2209#endif
2210
2211#if defined(JSON_HEDLEY_MESSAGE)
2212#undef JSON_HEDLEY_MESSAGE
2213#endif
2214#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2215# define JSON_HEDLEY_MESSAGE(msg) \
2216 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2217 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2218 JSON_HEDLEY_PRAGMA(message msg) \
2219 JSON_HEDLEY_DIAGNOSTIC_POP
2220#elif \
2221 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2222 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2223# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2224#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2225# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2226#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2227# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2228#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2229# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2230#else
2231# define JSON_HEDLEY_MESSAGE(msg)
2232#endif
2233
2234#if defined(JSON_HEDLEY_WARNING)
2235#undef JSON_HEDLEY_WARNING
2236#endif
2237#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2238# define JSON_HEDLEY_WARNING(msg) \
2239 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2240 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2241 JSON_HEDLEY_PRAGMA(clang warning msg) \
2242 JSON_HEDLEY_DIAGNOSTIC_POP
2243#elif \
2244 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2245 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2246 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2247# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2248#elif \
2249 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2250 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2251# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2252#else
2253# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2254#endif
2255
2256#if defined(JSON_HEDLEY_REQUIRE)
2257#undef JSON_HEDLEY_REQUIRE
2258#endif
2259#if defined(JSON_HEDLEY_REQUIRE_MSG)
2260#undef JSON_HEDLEY_REQUIRE_MSG
2261#endif
2262#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2263# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2264# define JSON_HEDLEY_REQUIRE(expr) \
2265 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2266 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2267 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2268 JSON_HEDLEY_DIAGNOSTIC_POP
2269# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2270 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2271 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2272 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2273 JSON_HEDLEY_DIAGNOSTIC_POP
2274# else
2275# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2276# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2277# endif
2278#else
2279# define JSON_HEDLEY_REQUIRE(expr)
2280# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2281#endif
2282
2283#if defined(JSON_HEDLEY_FLAGS)
2284#undef JSON_HEDLEY_FLAGS
2285#endif
2286#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2287#define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2288#else
2289#define JSON_HEDLEY_FLAGS
2290#endif
2291
2292#if defined(JSON_HEDLEY_FLAGS_CAST)
2293#undef JSON_HEDLEY_FLAGS_CAST
2294#endif
2295#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2296# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2297 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2298 _Pragma("warning(disable:188)") \
2299 ((T) (expr)); \
2300 JSON_HEDLEY_DIAGNOSTIC_POP \
2301 }))
2302#else
2303# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2304#endif
2305
2306#if defined(JSON_HEDLEY_EMPTY_BASES)
2307#undef JSON_HEDLEY_EMPTY_BASES
2308#endif
2309#if \
2310 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2311 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2312#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2313#else
2314#define JSON_HEDLEY_EMPTY_BASES
2315#endif
2316
2317 /* Remaining macros are deprecated. */
2318
2319#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2320#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2321#endif
2322#if defined(__clang__)
2323#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2324#else
2325#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2326#endif
2327
2328#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2329#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2330#endif
2331#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2332
2333#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2334#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2335#endif
2336#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2337
2338#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2339#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2340#endif
2341#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2342
2343#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2344#undef JSON_HEDLEY_CLANG_HAS_FEATURE
2345#endif
2346#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2347
2348#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2349#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2350#endif
2351#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2352
2353#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2354#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2355#endif
2356#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2357
2358#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2359#undef JSON_HEDLEY_CLANG_HAS_WARNING
2360#endif
2361#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2362
2363#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2364
2365
2366// This file contains all internal macro definitions (except those affecting ABI)
2367// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2368
2369// #include <nlohmann/detail/abi_macros.hpp>
2370
2371
2372// exclude unsupported compilers
2373#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2374#if defined(__clang__)
2375#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2376#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2377#endif
2378#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2379#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2380#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2381#endif
2382#endif
2383#endif
2384
2385// C++ language standard detection
2386// if the user manually specified the used c++ version this is skipped
2387#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2388#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2389#define JSON_HAS_CPP_20
2390#define JSON_HAS_CPP_17
2391#define JSON_HAS_CPP_14
2392#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2393#define JSON_HAS_CPP_17
2394#define JSON_HAS_CPP_14
2395#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2396#define JSON_HAS_CPP_14
2397#endif
2398// the cpp 11 flag is always specified because it is the minimal required version
2399#define JSON_HAS_CPP_11
2400#endif
2401
2402#ifdef __has_include
2403#if __has_include(<version>)
2404#include <version>
2405#endif
2406#endif
2407
2408#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2409#ifdef JSON_HAS_CPP_17
2410#if defined(__cpp_lib_filesystem)
2411#define JSON_HAS_FILESYSTEM 1
2412#elif defined(__cpp_lib_experimental_filesystem)
2413#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2414#elif !defined(__has_include)
2415#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2416#elif __has_include(<filesystem>)
2417#define JSON_HAS_FILESYSTEM 1
2418#elif __has_include(<experimental/filesystem>)
2419#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2420#endif
2421
2422// std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2423#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2424#undef JSON_HAS_FILESYSTEM
2425#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2426#endif
2427
2428// no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2429#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2430#undef JSON_HAS_FILESYSTEM
2431#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2432#endif
2433
2434// no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2435#if defined(__clang_major__) && __clang_major__ < 7
2436#undef JSON_HAS_FILESYSTEM
2437#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2438#endif
2439
2440// no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2441#if defined(_MSC_VER) && _MSC_VER < 1914
2442#undef JSON_HAS_FILESYSTEM
2443#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2444#endif
2445
2446// no filesystem support before iOS 13
2447#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2448#undef JSON_HAS_FILESYSTEM
2449#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2450#endif
2451
2452// no filesystem support before macOS Catalina
2453#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2454#undef JSON_HAS_FILESYSTEM
2455#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2456#endif
2457#endif
2458#endif
2459
2460#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2461#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2462#endif
2463
2464#ifndef JSON_HAS_FILESYSTEM
2465#define JSON_HAS_FILESYSTEM 0
2466#endif
2467
2468#ifndef JSON_HAS_THREE_WAY_COMPARISON
2469#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2470 && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2471#define JSON_HAS_THREE_WAY_COMPARISON 1
2472#else
2473#define JSON_HAS_THREE_WAY_COMPARISON 0
2474#endif
2475#endif
2476
2477#ifndef JSON_HAS_RANGES
2478 // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2479#if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2480#define JSON_HAS_RANGES 0
2481#elif defined(__cpp_lib_ranges)
2482#define JSON_HAS_RANGES 1
2483#else
2484#define JSON_HAS_RANGES 0
2485#endif
2486#endif
2487
2488#ifdef JSON_HAS_CPP_17
2489#define JSON_INLINE_VARIABLE inline
2490#else
2491#define JSON_INLINE_VARIABLE
2492#endif
2493
2494#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2495#define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2496#else
2497#define JSON_NO_UNIQUE_ADDRESS
2498#endif
2499
2500// disable documentation warnings on clang
2501#if defined(__clang__)
2502#pragma clang diagnostic push
2503#pragma clang diagnostic ignored "-Wdocumentation"
2504#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2505#endif
2506
2507// allow disabling exceptions
2508#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2509#define JSON_THROW(exception) throw exception
2510#define JSON_TRY try
2511#define JSON_CATCH(exception) catch(exception)
2512#define JSON_INTERNAL_CATCH(exception) catch(exception)
2513#else
2514#include <cstdlib>
2515#define JSON_THROW(exception) std::abort()
2516#define JSON_TRY if(true)
2517#define JSON_CATCH(exception) if(false)
2518#define JSON_INTERNAL_CATCH(exception) if(false)
2519#endif
2520
2521// override exception macros
2522#if defined(JSON_THROW_USER)
2523#undef JSON_THROW
2524#define JSON_THROW JSON_THROW_USER
2525#endif
2526#if defined(JSON_TRY_USER)
2527#undef JSON_TRY
2528#define JSON_TRY JSON_TRY_USER
2529#endif
2530#if defined(JSON_CATCH_USER)
2531#undef JSON_CATCH
2532#define JSON_CATCH JSON_CATCH_USER
2533#undef JSON_INTERNAL_CATCH
2534#define JSON_INTERNAL_CATCH JSON_CATCH_USER
2535#endif
2536#if defined(JSON_INTERNAL_CATCH_USER)
2537#undef JSON_INTERNAL_CATCH
2538#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2539#endif
2540
2541// allow overriding assert
2542#if !defined(JSON_ASSERT)
2543#include <cassert> // assert
2544#define JSON_ASSERT(x) assert(x)
2545#endif
2546
2547// allow to access some private functions (needed by the test suite)
2548#if defined(JSON_TESTS_PRIVATE)
2549#define JSON_PRIVATE_UNLESS_TESTED public
2550#else
2551#define JSON_PRIVATE_UNLESS_TESTED private
2552#endif
2553
2559#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2560 template<typename BasicJsonType> \
2561 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2562 { \
2563 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2564 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2565 auto it = std::find_if(std::begin(m), std::end(m), \
2566 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2567 { \
2568 return ej_pair.first == e; \
2569 }); \
2570 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2571 } \
2572 template<typename BasicJsonType> \
2573 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2574 { \
2575 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2576 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2577 auto it = std::find_if(std::begin(m), std::end(m), \
2578 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2579 { \
2580 return ej_pair.second == j; \
2581 }); \
2582 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2583 }
2584
2585// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2586// may be removed in the future once the class is split.
2587
2588#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2589 template<template<typename, typename, typename...> class ObjectType, \
2590 template<typename, typename...> class ArrayType, \
2591 class StringType, class BooleanType, class NumberIntegerType, \
2592 class NumberUnsignedType, class NumberFloatType, \
2593 template<typename> class AllocatorType, \
2594 template<typename, typename = void> class JSONSerializer, \
2595 class BinaryType, \
2596 class CustomBaseClass>
2597
2598#define NLOHMANN_BASIC_JSON_TPL \
2599 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2600 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2601 AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
2602
2603// Macros to simplify conversion from/to types
2604
2605#define NLOHMANN_JSON_EXPAND( x ) x
2606#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2607#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2608 NLOHMANN_JSON_PASTE64, \
2609 NLOHMANN_JSON_PASTE63, \
2610 NLOHMANN_JSON_PASTE62, \
2611 NLOHMANN_JSON_PASTE61, \
2612 NLOHMANN_JSON_PASTE60, \
2613 NLOHMANN_JSON_PASTE59, \
2614 NLOHMANN_JSON_PASTE58, \
2615 NLOHMANN_JSON_PASTE57, \
2616 NLOHMANN_JSON_PASTE56, \
2617 NLOHMANN_JSON_PASTE55, \
2618 NLOHMANN_JSON_PASTE54, \
2619 NLOHMANN_JSON_PASTE53, \
2620 NLOHMANN_JSON_PASTE52, \
2621 NLOHMANN_JSON_PASTE51, \
2622 NLOHMANN_JSON_PASTE50, \
2623 NLOHMANN_JSON_PASTE49, \
2624 NLOHMANN_JSON_PASTE48, \
2625 NLOHMANN_JSON_PASTE47, \
2626 NLOHMANN_JSON_PASTE46, \
2627 NLOHMANN_JSON_PASTE45, \
2628 NLOHMANN_JSON_PASTE44, \
2629 NLOHMANN_JSON_PASTE43, \
2630 NLOHMANN_JSON_PASTE42, \
2631 NLOHMANN_JSON_PASTE41, \
2632 NLOHMANN_JSON_PASTE40, \
2633 NLOHMANN_JSON_PASTE39, \
2634 NLOHMANN_JSON_PASTE38, \
2635 NLOHMANN_JSON_PASTE37, \
2636 NLOHMANN_JSON_PASTE36, \
2637 NLOHMANN_JSON_PASTE35, \
2638 NLOHMANN_JSON_PASTE34, \
2639 NLOHMANN_JSON_PASTE33, \
2640 NLOHMANN_JSON_PASTE32, \
2641 NLOHMANN_JSON_PASTE31, \
2642 NLOHMANN_JSON_PASTE30, \
2643 NLOHMANN_JSON_PASTE29, \
2644 NLOHMANN_JSON_PASTE28, \
2645 NLOHMANN_JSON_PASTE27, \
2646 NLOHMANN_JSON_PASTE26, \
2647 NLOHMANN_JSON_PASTE25, \
2648 NLOHMANN_JSON_PASTE24, \
2649 NLOHMANN_JSON_PASTE23, \
2650 NLOHMANN_JSON_PASTE22, \
2651 NLOHMANN_JSON_PASTE21, \
2652 NLOHMANN_JSON_PASTE20, \
2653 NLOHMANN_JSON_PASTE19, \
2654 NLOHMANN_JSON_PASTE18, \
2655 NLOHMANN_JSON_PASTE17, \
2656 NLOHMANN_JSON_PASTE16, \
2657 NLOHMANN_JSON_PASTE15, \
2658 NLOHMANN_JSON_PASTE14, \
2659 NLOHMANN_JSON_PASTE13, \
2660 NLOHMANN_JSON_PASTE12, \
2661 NLOHMANN_JSON_PASTE11, \
2662 NLOHMANN_JSON_PASTE10, \
2663 NLOHMANN_JSON_PASTE9, \
2664 NLOHMANN_JSON_PASTE8, \
2665 NLOHMANN_JSON_PASTE7, \
2666 NLOHMANN_JSON_PASTE6, \
2667 NLOHMANN_JSON_PASTE5, \
2668 NLOHMANN_JSON_PASTE4, \
2669 NLOHMANN_JSON_PASTE3, \
2670 NLOHMANN_JSON_PASTE2, \
2671 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2672#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2673#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2674#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2675#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2676#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2677#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2678#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2679#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2680#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2681#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2682#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2683#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2684#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2685#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2686#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2687#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2688#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2689#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2690#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2691#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2692#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2693#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2694#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2695#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2696#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2697#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2698#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2699#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2700#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2701#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2702#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2703#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2704#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2705#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2706#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2707#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2708#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2709#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2710#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2711#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2712#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2713#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2714#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2715#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2716#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2717#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2718#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2719#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2720#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2721#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2722#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2723#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2724#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2725#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2726#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2727#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2728#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2729#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2730#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2731#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2732#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2733#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2734#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2735
2736#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2737#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2738#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2739
2745#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2746 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2747 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2748
2749#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2750 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2751 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2752
2758#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2759 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2760 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2761
2762#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2763 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2764 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2765
2766
2767// inspired from https://stackoverflow.com/a/26745591
2768// allows to call any std function as if (e.g. with begin):
2769// using std::begin; begin(x);
2770//
2771// it allows using the detected idiom to retrieve the return type
2772// of such an expression
2773#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2774 namespace detail { \
2775 using std::std_name; \
2776 \
2777 template<typename... T> \
2778 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2779 } \
2780 \
2781 namespace detail2 { \
2782 struct std_name##_tag \
2783 { \
2784 }; \
2785 \
2786 template<typename... T> \
2787 std_name##_tag std_name(T&&...); \
2788 \
2789 template<typename... T> \
2790 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2791 \
2792 template<typename... T> \
2793 struct would_call_std_##std_name \
2794 { \
2795 static constexpr auto const value = ::nlohmann::detail:: \
2796 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2797 }; \
2798 } /* namespace detail2 */ \
2799 \
2800 template<typename... T> \
2801 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2802 { \
2803 }
2804
2805#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2806#define JSON_USE_IMPLICIT_CONVERSIONS 1
2807#endif
2808
2809#if JSON_USE_IMPLICIT_CONVERSIONS
2810#define JSON_EXPLICIT
2811#else
2812#define JSON_EXPLICIT explicit
2813#endif
2814
2815#ifndef JSON_DISABLE_ENUM_SERIALIZATION
2816#define JSON_DISABLE_ENUM_SERIALIZATION 0
2817#endif
2818
2819#ifndef JSON_USE_GLOBAL_UDLS
2820#define JSON_USE_GLOBAL_UDLS 1
2821#endif
2822
2823#if JSON_HAS_THREE_WAY_COMPARISON
2824#include <compare> // partial_ordering
2825#endif
2826
2828namespace detail
2829{
2830
2832 // JSON type enumeration //
2834
2859 enum class value_t : std::uint8_t
2860 {
2861 null,
2862 object,
2863 array,
2864 string,
2865 boolean,
2868 number_float,
2869 binary,
2870 discarded
2871 };
2872
2886#if JSON_HAS_THREE_WAY_COMPARISON
2887 inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2888#else
2889 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2890#endif
2891 {
2892 static constexpr std::array<std::uint8_t, 9> order = { {
2893 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2894 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2895 6 /* binary */
2896 }
2897 };
2898
2899 const auto l_index = static_cast<std::size_t>(lhs);
2900 const auto r_index = static_cast<std::size_t>(rhs);
2901#if JSON_HAS_THREE_WAY_COMPARISON
2902 if (l_index < order.size() && r_index < order.size())
2903 {
2904 return order[l_index] <=> order[r_index]; // *NOPAD*
2905 }
2906 return std::partial_ordering::unordered;
2907#else
2908 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2909#endif
2910 }
2911
2912 // GCC selects the built-in operator< over an operator rewritten from
2913 // a user-defined spaceship operator
2914 // Clang, MSVC, and ICC select the rewritten candidate
2915 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2916#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2917 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2918 {
2919 return std::is_lt(lhs <=> rhs); // *NOPAD*
2920 }
2921#endif
2922
2923} // namespace detail
2925
2926// #include <nlohmann/detail/string_escape.hpp>
2927// __ _____ _____ _____
2928// __| | __| | | | JSON for Modern C++
2929// | | |__ | | | | | | version 3.11.2
2930// |_____|_____|_____|_|___| https://github.com/nlohmann/json
2931//
2932// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
2933// SPDX-License-Identifier: MIT
2934
2935
2936
2937// #include <nlohmann/detail/abi_macros.hpp>
2938
2939
2941namespace detail
2942{
2943
2957 template<typename StringType>
2958 inline void replace_substring(StringType& s, const StringType& f,
2959 const StringType& t)
2960 {
2961 JSON_ASSERT(!f.empty());
2962 for (auto pos = s.find(f); // find first occurrence of f
2963 pos != StringType::npos; // make sure f was found
2964 s.replace(pos, f.size(), t), // replace with t, and
2965 pos = s.find(f, pos + t.size())) // find next occurrence of f
2966 {
2967 }
2968 }
2969
2977 template<typename StringType>
2978 inline StringType escape(StringType s)
2979 {
2980 replace_substring(s, StringType{ "~" }, StringType{ "~0" });
2981 replace_substring(s, StringType{ "/" }, StringType{ "~1" });
2982 return s;
2983 }
2984
2992 template<typename StringType>
2993 static void unescape(StringType& s)
2994 {
2995 replace_substring(s, StringType{ "~1" }, StringType{ "/" });
2996 replace_substring(s, StringType{ "~0" }, StringType{ "~" });
2997 }
2998
2999} // namespace detail
3001
3002// #include <nlohmann/detail/input/position_t.hpp>
3003// __ _____ _____ _____
3004// __| | __| | | | JSON for Modern C++
3005// | | |__ | | | | | | version 3.11.2
3006// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3007//
3008// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3009// SPDX-License-Identifier: MIT
3010
3011
3012
3013#include <cstddef> // size_t
3014
3015// #include <nlohmann/detail/abi_macros.hpp>
3016
3017
3019namespace detail
3020{
3021
3024 {
3026 std::size_t chars_read_total = 0;
3030 std::size_t lines_read = 0;
3031
3033 constexpr operator size_t() const
3034 {
3035 return chars_read_total;
3036 }
3037 };
3038
3039} // namespace detail
3041
3042// #include <nlohmann/detail/macro_scope.hpp>
3043
3044// #include <nlohmann/detail/meta/cpp_future.hpp>
3045// __ _____ _____ _____
3046// __| | __| | | | JSON for Modern C++
3047// | | |__ | | | | | | version 3.11.2
3048// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3049//
3050// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3051// SPDX-FileCopyrightText: 2018 The Abseil Authors
3052// SPDX-License-Identifier: MIT
3053
3054
3055
3056#include <array> // array
3057#include <cstddef> // size_t
3058#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3059#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3060
3061// #include <nlohmann/detail/macro_scope.hpp>
3062
3063
3065namespace detail
3066{
3067
3068 template<typename T>
3069 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3070
3071#ifdef JSON_HAS_CPP_14
3072
3073 // the following utilities are natively available in C++14
3074 using std::enable_if_t;
3075 using std::index_sequence;
3076 using std::make_index_sequence;
3077 using std::index_sequence_for;
3078
3079#else
3080
3081 // alias templates to reduce boilerplate
3082 template<bool B, typename T = void>
3083 using enable_if_t = typename std::enable_if<B, T>::type;
3084
3085 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3086 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3087
3089
3090 // integer_sequence
3091 //
3092 // Class template representing a compile-time integer sequence. An instantiation
3093 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3094 // type through its template arguments (which is a common need when
3095 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3096 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3097 //
3098 // Example:
3099 //
3100 // template< class T, T... Ints >
3101 // void user_function(integer_sequence<T, Ints...>);
3102 //
3103 // int main()
3104 // {
3105 // // user_function's `T` will be deduced to `int` and `Ints...`
3106 // // will be deduced to `0, 1, 2, 3, 4`.
3107 // user_function(make_integer_sequence<int, 5>());
3108 // }
3109 template <typename T, T... Ints>
3111 {
3112 using value_type = T;
3113 static constexpr std::size_t size() noexcept
3114 {
3115 return sizeof...(Ints);
3116 }
3117 };
3118
3119 // index_sequence
3120 //
3121 // A helper template for an `integer_sequence` of `size_t`,
3122 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3123 // `std::index_sequence`.
3124 template <size_t... Ints>
3125 using index_sequence = integer_sequence<size_t, Ints...>;
3126
3127 namespace utility_internal
3128 {
3129
3130 template <typename Seq, size_t SeqSize, size_t Rem>
3131 struct Extend;
3132
3133 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3134 template <typename T, T... Ints, size_t SeqSize>
3135 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3136 {
3137 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3138 };
3139
3140 template <typename T, T... Ints, size_t SeqSize>
3141 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3142 {
3143 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3144 };
3145
3146 // Recursion helper for 'make_integer_sequence<T, N>'.
3147 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3148 template <typename T, size_t N>
3149 struct Gen
3150 {
3151 using type =
3152 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3153 };
3154
3155 template <typename T>
3156 struct Gen<T, 0>
3157 {
3159 };
3160
3161 } // namespace utility_internal
3162
3163 // Compile-time sequences of integers
3164
3165 // make_integer_sequence
3166 //
3167 // This template alias is equivalent to
3168 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3169 // replacement for C++14's `std::make_integer_sequence`.
3170 template <typename T, T N>
3172
3173 // make_index_sequence
3174 //
3175 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3176 // and is designed to be a drop-in replacement for C++14's
3177 // `std::make_index_sequence`.
3178 template <size_t N>
3180
3181 // index_sequence_for
3182 //
3183 // Converts a typename pack into an index sequence of the same length, and
3184 // is designed to be a drop-in replacement for C++14's
3185 // `std::index_sequence_for()`
3186 template <typename... Ts>
3188
3190
3191#endif
3192
3193// dispatch utility (taken from ranges-v3)
3194 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3195 template<> struct priority_tag<0> {};
3196
3197 // taken from ranges-v3
3198 template<typename T>
3200 {
3201 static JSON_INLINE_VARIABLE constexpr T value{};
3202 };
3203
3204#ifndef JSON_HAS_CPP_17
3205 template<typename T>
3206 constexpr T static_const<T>::value;
3207#endif
3208
3209 template<typename T, typename... Args>
3210 inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3211 {
3212 return std::array<T, sizeof...(Args)> { {static_cast<T>(std::forward<Args>(args))...}};
3213 }
3214
3215} // namespace detail
3217
3218// #include <nlohmann/detail/meta/type_traits.hpp>
3219// __ _____ _____ _____
3220// __| | __| | | | JSON for Modern C++
3221// | | |__ | | | | | | version 3.11.2
3222// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3223//
3224// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3225// SPDX-License-Identifier: MIT
3226
3227
3228
3229#include <limits> // numeric_limits
3230#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3231#include <utility> // declval
3232#include <tuple> // tuple
3233
3234// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3235// __ _____ _____ _____
3236// __| | __| | | | JSON for Modern C++
3237// | | |__ | | | | | | version 3.11.2
3238// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3239//
3240// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3241// SPDX-License-Identifier: MIT
3242
3243
3244
3245#include <iterator> // random_access_iterator_tag
3246
3247// #include <nlohmann/detail/abi_macros.hpp>
3248
3249// #include <nlohmann/detail/meta/void_t.hpp>
3250
3251// #include <nlohmann/detail/meta/cpp_future.hpp>
3252
3253
3255namespace detail
3256{
3257
3258 template<typename It, typename = void>
3260
3261 template<typename It>
3263 It,
3264 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3265 typename It::reference, typename It::iterator_category >>
3266 {
3267 using difference_type = typename It::difference_type;
3268 using value_type = typename It::value_type;
3269 using pointer = typename It::pointer;
3270 using reference = typename It::reference;
3271 using iterator_category = typename It::iterator_category;
3272 };
3273
3274 // This is required as some compilers implement std::iterator_traits in a way that
3275 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3276 template<typename T, typename = void>
3278 {
3279 };
3280
3281 template<typename T>
3282 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3283 : iterator_types<T>
3284 {
3285 };
3286
3287 template<typename T>
3289 {
3290 using iterator_category = std::random_access_iterator_tag;
3291 using value_type = T;
3292 using difference_type = ptrdiff_t;
3293 using pointer = T*;
3294 using reference = T&;
3295 };
3296
3297} // namespace detail
3299
3300// #include <nlohmann/detail/macro_scope.hpp>
3301
3302// #include <nlohmann/detail/meta/call_std/begin.hpp>
3303// __ _____ _____ _____
3304// __| | __| | | | JSON for Modern C++
3305// | | |__ | | | | | | version 3.11.2
3306// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3307//
3308// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3309// SPDX-License-Identifier: MIT
3310
3311
3312
3313// #include <nlohmann/detail/macro_scope.hpp>
3314
3315
3317
3319
3321
3322// #include <nlohmann/detail/meta/call_std/end.hpp>
3323// __ _____ _____ _____
3324// __| | __| | | | JSON for Modern C++
3325// | | |__ | | | | | | version 3.11.2
3326// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3327//
3328// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3329// SPDX-License-Identifier: MIT
3330
3331
3332
3333// #include <nlohmann/detail/macro_scope.hpp>
3334
3335
3337
3339
3341
3342// #include <nlohmann/detail/meta/cpp_future.hpp>
3343
3344// #include <nlohmann/detail/meta/detected.hpp>
3345
3346// #include <nlohmann/json_fwd.hpp>
3347// __ _____ _____ _____
3348// __| | __| | | | JSON for Modern C++
3349// | | |__ | | | | | | version 3.11.2
3350// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3351//
3352// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3353// SPDX-License-Identifier: MIT
3354
3355#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3356#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3357
3358#include <cstdint> // int64_t, uint64_t
3359#include <map> // map
3360#include <memory> // allocator
3361#include <string> // string
3362#include <vector> // vector
3363
3364// #include <nlohmann/detail/abi_macros.hpp>
3365
3366
3373
3381template<typename T = void, typename SFINAE = void>
3382struct adl_serializer;
3383
3386template<template<typename U, typename V, typename... Args> class ObjectType =
3387 std::map,
3388 template<typename U, typename... Args> class ArrayType = std::vector,
3389 class StringType = std::string, class BooleanType = bool,
3390 class NumberIntegerType = std::int64_t,
3391 class NumberUnsignedType = std::uint64_t,
3392 class NumberFloatType = double,
3393 template<typename U> class AllocatorType = std::allocator,
3394 template<typename T, typename SFINAE = void> class JSONSerializer =
3396 class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
3397 class CustomBaseClass = void>
3398class basic_json;
3399
3402template<typename RefStringType>
3403class json_pointer;
3404
3410
3413template<class Key, class T, class IgnoredLess, class Allocator>
3414struct ordered_map;
3415
3419
3421
3422#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3423
3424
3434namespace detail
3435{
3436
3438 // helpers //
3440
3441 // Note to maintainers:
3442 //
3443 // Every trait in this file expects a non CV-qualified type.
3444 // The only exceptions are in the 'aliases for detected' section
3445 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3446 //
3447 // In this case, T has to be properly CV-qualified to constraint the function arguments
3448 // (e.g. to_json(BasicJsonType&, const T&))
3449
3450 template<typename> struct is_basic_json : std::false_type {};
3451
3453 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3454
3455 // used by exceptions create() member functions
3456 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3457 // false_type otherwise
3458 template<typename BasicJsonContext>
3460 std::integral_constant < bool,
3461 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3462 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3463 {};
3464
3466 // json_ref helpers //
3468
3469 template<typename>
3470 class json_ref;
3471
3472 template<typename>
3473 struct is_json_ref : std::false_type {};
3474
3475 template<typename T>
3476 struct is_json_ref<json_ref<T>> : std::true_type {};
3477
3479 // aliases for detected //
3481
3482 template<typename T>
3483 using mapped_type_t = typename T::mapped_type;
3484
3485 template<typename T>
3486 using key_type_t = typename T::key_type;
3487
3488 template<typename T>
3489 using value_type_t = typename T::value_type;
3490
3491 template<typename T>
3492 using difference_type_t = typename T::difference_type;
3493
3494 template<typename T>
3495 using pointer_t = typename T::pointer;
3496
3497 template<typename T>
3498 using reference_t = typename T::reference;
3499
3500 template<typename T>
3501 using iterator_category_t = typename T::iterator_category;
3502
3503 template<typename T, typename... Args>
3504 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3505
3506 template<typename T, typename... Args>
3507 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3508
3509 template<typename T, typename U>
3510 using get_template_function = decltype(std::declval<T>().template get<U>());
3511
3512 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3513 template<typename BasicJsonType, typename T, typename = void>
3514 struct has_from_json : std::false_type {};
3515
3516 // trait checking if j.get<T> is valid
3517 // use this trait instead of std::is_constructible or std::is_convertible,
3518 // both rely on, or make use of implicit conversions, and thus fail when T
3519 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3520 template <typename BasicJsonType, typename T>
3522 {
3524 };
3525
3526 template<typename BasicJsonType, typename T>
3527 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3528 {
3529 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3530
3531 static constexpr bool value =
3533 const BasicJsonType&, T&>::value;
3534 };
3535
3536 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3537 // this overload is used for non-default-constructible user-defined-types
3538 template<typename BasicJsonType, typename T, typename = void>
3539 struct has_non_default_from_json : std::false_type {};
3540
3541 template<typename BasicJsonType, typename T>
3542 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3543 {
3544 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3545
3546 static constexpr bool value =
3548 const BasicJsonType&>::value;
3549 };
3550
3551 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3552 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3553 template<typename BasicJsonType, typename T, typename = void>
3554 struct has_to_json : std::false_type {};
3555
3556 template<typename BasicJsonType, typename T>
3557 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3558 {
3559 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3560
3561 static constexpr bool value =
3562 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3563 T>::value;
3564 };
3565
3566 template<typename T>
3567 using detect_key_compare = typename T::key_compare;
3568
3569 template<typename T>
3570 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3571
3572 // obtains the actual object key comparator
3573 template<typename BasicJsonType>
3575 {
3576 using object_t = typename BasicJsonType::object_t;
3577 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3578 using type = typename std::conditional < has_key_compare<object_t>::value,
3579 typename object_t::key_compare, object_comparator_t>::type;
3580 };
3581
3582 template<typename BasicJsonType>
3584
3586 // is_ functions //
3588
3589 // https://en.cppreference.com/w/cpp/types/conjunction
3590 template<class...> struct conjunction : std::true_type { };
3591 template<class B> struct conjunction<B> : B { };
3592 template<class B, class... Bn>
3593 struct conjunction<B, Bn...>
3594 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3595
3596 // https://en.cppreference.com/w/cpp/types/negation
3597 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3598
3599 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3600 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3601 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3602 template <typename T>
3603 struct is_default_constructible : std::is_default_constructible<T> {};
3604
3605 template <typename T1, typename T2>
3606 struct is_default_constructible<std::pair<T1, T2>>
3607 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3608
3609 template <typename T1, typename T2>
3610 struct is_default_constructible<const std::pair<T1, T2>>
3611 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3612
3613 template <typename... Ts>
3614 struct is_default_constructible<std::tuple<Ts...>>
3615 : conjunction<is_default_constructible<Ts>...> {};
3616
3617 template <typename... Ts>
3618 struct is_default_constructible<const std::tuple<Ts...>>
3619 : conjunction<is_default_constructible<Ts>...> {};
3620
3621
3622 template <typename T, typename... Args>
3623 struct is_constructible : std::is_constructible<T, Args...> {};
3624
3625 template <typename T1, typename T2>
3626 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3627
3628 template <typename T1, typename T2>
3629 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3630
3631 template <typename... Ts>
3632 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3633
3634 template <typename... Ts>
3635 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3636
3637
3638 template<typename T, typename = void>
3639 struct is_iterator_traits : std::false_type {};
3640
3641 template<typename T>
3643 {
3644 private:
3645 using traits = iterator_traits<T>;
3646
3647 public:
3648 static constexpr auto value =
3654 };
3655
3656 template<typename T>
3658 {
3659 private:
3660 using t_ref = typename std::add_lvalue_reference<T>::type;
3661
3662 using iterator = detected_t<result_of_begin, t_ref>;
3663 using sentinel = detected_t<result_of_end, t_ref>;
3664
3665 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3666 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3667 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3668 static constexpr auto is_iterator_begin =
3670
3671 public:
3672 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value&& is_iterator_begin;
3673 };
3674
3675 template<typename R>
3676 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3677
3678 template<typename T>
3680
3681 // The following implementation of is_complete_type is taken from
3682 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3683 // and is written by Xiang Fan who agreed to using it in this library.
3684
3685 template<typename T, typename = void>
3686 struct is_complete_type : std::false_type {};
3687
3688 template<typename T>
3689 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3690
3691 template<typename BasicJsonType, typename CompatibleObjectType,
3692 typename = void>
3693 struct is_compatible_object_type_impl : std::false_type {};
3694
3695 template<typename BasicJsonType, typename CompatibleObjectType>
3697 BasicJsonType, CompatibleObjectType,
3698 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3699 is_detected<key_type_t, CompatibleObjectType>::value >>
3700 {
3701 using object_t = typename BasicJsonType::object_t;
3702
3703 // macOS's is_constructible does not play well with nonesuch...
3704 static constexpr bool value =
3705 is_constructible<typename object_t::key_type,
3706 typename CompatibleObjectType::key_type>::value&&
3707 is_constructible<typename object_t::mapped_type,
3708 typename CompatibleObjectType::mapped_type>::value;
3709 };
3710
3711 template<typename BasicJsonType, typename CompatibleObjectType>
3713 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3714
3715 template<typename BasicJsonType, typename ConstructibleObjectType,
3716 typename = void>
3717 struct is_constructible_object_type_impl : std::false_type {};
3718
3719 template<typename BasicJsonType, typename ConstructibleObjectType>
3721 BasicJsonType, ConstructibleObjectType,
3722 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3723 is_detected<key_type_t, ConstructibleObjectType>::value >>
3724 {
3725 using object_t = typename BasicJsonType::object_t;
3726
3727 static constexpr bool value =
3729 (std::is_move_assignable<ConstructibleObjectType>::value ||
3730 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3731 (is_constructible<typename ConstructibleObjectType::key_type,
3732 typename object_t::key_type>::value &&
3733 std::is_same <
3734 typename object_t::mapped_type,
3735 typename ConstructibleObjectType::mapped_type >::value)) ||
3736 (has_from_json<BasicJsonType,
3737 typename ConstructibleObjectType::mapped_type>::value ||
3739 BasicJsonType,
3740 typename ConstructibleObjectType::mapped_type >::value);
3741 };
3742
3743 template<typename BasicJsonType, typename ConstructibleObjectType>
3745 : is_constructible_object_type_impl<BasicJsonType,
3746 ConstructibleObjectType> {};
3747
3748 template<typename BasicJsonType, typename CompatibleStringType>
3750 {
3751 static constexpr auto value =
3753 };
3754
3755 template<typename BasicJsonType, typename ConstructibleStringType>
3757 {
3758 // launder type through decltype() to fix compilation failure on ICPC
3759#ifdef __INTEL_COMPILER
3760 using laundered_type = decltype(std::declval<ConstructibleStringType>());
3761#else
3762 using laundered_type = ConstructibleStringType;
3763#endif
3764
3765 static constexpr auto value =
3766 conjunction <
3768 is_detected_exact<typename BasicJsonType::string_t::value_type,
3770 };
3771
3772 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3773 struct is_compatible_array_type_impl : std::false_type {};
3774
3775 template<typename BasicJsonType, typename CompatibleArrayType>
3777 BasicJsonType, CompatibleArrayType,
3778 enable_if_t <
3779 is_detected<iterator_t, CompatibleArrayType>::value&&
3780 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value &&
3781 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3782 // c.f. https://github.com/nlohmann/json/pull/3073
3783 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3784 {
3785 static constexpr bool value =
3786 is_constructible<BasicJsonType,
3788 };
3789
3790 template<typename BasicJsonType, typename CompatibleArrayType>
3792 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3793
3794 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3795 struct is_constructible_array_type_impl : std::false_type {};
3796
3797 template<typename BasicJsonType, typename ConstructibleArrayType>
3799 BasicJsonType, ConstructibleArrayType,
3800 enable_if_t<std::is_same<ConstructibleArrayType,
3801 typename BasicJsonType::value_type>::value >>
3802 : std::true_type {};
3803
3804 template<typename BasicJsonType, typename ConstructibleArrayType>
3806 BasicJsonType, ConstructibleArrayType,
3807 enable_if_t < !std::is_same<ConstructibleArrayType,
3808 typename BasicJsonType::value_type>::value &&
3809 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3810 is_default_constructible<ConstructibleArrayType>::value &&
3811 (std::is_move_assignable<ConstructibleArrayType>::value ||
3812 std::is_copy_assignable<ConstructibleArrayType>::value) &&
3813 is_detected<iterator_t, ConstructibleArrayType>::value&&
3814 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3815 is_detected<range_value_t, ConstructibleArrayType>::value &&
3816 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3817 // c.f. https://github.com/nlohmann/json/pull/3073
3818 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3820 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3821 {
3823
3824 static constexpr bool value =
3825 std::is_same<value_type,
3826 typename BasicJsonType::array_t::value_type>::value ||
3827 has_from_json<BasicJsonType,
3830 BasicJsonType,
3832 };
3833
3834 template<typename BasicJsonType, typename ConstructibleArrayType>
3836 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3837
3838 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3839 typename = void>
3840 struct is_compatible_integer_type_impl : std::false_type {};
3841
3842 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3844 RealIntegerType, CompatibleNumberIntegerType,
3845 enable_if_t < std::is_integral<RealIntegerType>::value&&
3846 std::is_integral<CompatibleNumberIntegerType>::value &&
3847 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3848 {
3849 // is there an assert somewhere on overflows?
3850 using RealLimits = std::numeric_limits<RealIntegerType>;
3851 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3852
3853 static constexpr auto value =
3854 is_constructible<RealIntegerType,
3855 CompatibleNumberIntegerType>::value&&
3856 CompatibleLimits::is_integer&&
3857 RealLimits::is_signed == CompatibleLimits::is_signed;
3858 };
3859
3860 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3862 : is_compatible_integer_type_impl<RealIntegerType,
3863 CompatibleNumberIntegerType> {};
3864
3865 template<typename BasicJsonType, typename CompatibleType, typename = void>
3866 struct is_compatible_type_impl : std::false_type {};
3867
3868 template<typename BasicJsonType, typename CompatibleType>
3870 BasicJsonType, CompatibleType,
3871 enable_if_t<is_complete_type<CompatibleType>::value >>
3872 {
3873 static constexpr bool value =
3875 };
3876
3877 template<typename BasicJsonType, typename CompatibleType>
3879 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3880
3881 template<typename T1, typename T2>
3882 struct is_constructible_tuple : std::false_type {};
3883
3884 template<typename T1, typename... Args>
3885 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3886
3887 template<typename BasicJsonType, typename T>
3888 struct is_json_iterator_of : std::false_type {};
3889
3890 template<typename BasicJsonType>
3891 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3892
3893 template<typename BasicJsonType>
3894 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3895 {};
3896
3897 // checks if a given type T is a template specialization of Primary
3898 template<template <typename...> class Primary, typename T>
3899 struct is_specialization_of : std::false_type {};
3900
3901 template<template <typename...> class Primary, typename... Args>
3902 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3903
3904 template<typename T>
3906
3907 // checks if A and B are comparable using Compare functor
3908 template<typename Compare, typename A, typename B, typename = void>
3909 struct is_comparable : std::false_type {};
3910
3911 template<typename Compare, typename A, typename B>
3912 struct is_comparable<Compare, A, B, void_t<
3913 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3914 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3915 >> : std::true_type {};
3916
3917 template<typename T>
3918 using detect_is_transparent = typename T::is_transparent;
3919
3920 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
3921 // see is_usable_as_basic_json_key_type below
3922 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3923 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3924 using is_usable_as_key_type = typename std::conditional <
3926 && !(ExcludeObjectKeyType&& std::is_same<KeyType,
3927 ObjectKeyType>::value)
3928 && (!RequireTransparentComparator
3929 || is_detected <detect_is_transparent, Comparator>::value)
3931 std::true_type,
3932 std::false_type >::type;
3933
3934 // type trait to check if KeyType can be used as object key
3935 // true if:
3936 // - KeyType is comparable with BasicJsonType::object_t::key_type
3937 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3938 // - the comparator is transparent or RequireTransparentComparator is false
3939 // - KeyType is not a JSON iterator or json_pointer
3940 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3941 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3942 using is_usable_as_basic_json_key_type = typename std::conditional <
3943 is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
3944 typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
3945 RequireTransparentComparator, ExcludeObjectKeyType>::value
3947 std::true_type,
3948 std::false_type >::type;
3949
3950 template<typename ObjectType, typename KeyType>
3951 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3952
3953 // type trait to check if object_t has an erase() member functions accepting KeyType
3954 template<typename BasicJsonType, typename KeyType>
3955 using has_erase_with_key_type = typename std::conditional <
3956 is_detected <
3958 typename BasicJsonType::object_t, KeyType >::value,
3959 std::true_type,
3960 std::false_type >::type;
3961
3962 // a naive helper to check if a type is an ordered_map (exploits the fact that
3963 // ordered_map inherits capacity() from std::vector)
3964 template <typename T>
3966 {
3967 using one = char;
3968
3969 struct two
3970 {
3971 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3972 };
3973
3974 template <typename C> static one test(decltype(&C::capacity));
3975 template <typename C> static two test(...);
3976
3977 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3978 };
3979
3980 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3981 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3983 {
3984 return static_cast<T>(value);
3985 }
3986
3987 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3989 {
3990 return value;
3991 }
3992
3993 template<typename... Types>
3995
3996 template<typename... Types>
3998
3999 template<typename... Types>
4001
4002 // there's a disjunction trait in another PR; replace when merged
4003 template<typename... Types>
4004 using same_sign = std::integral_constant < bool,
4005 all_signed<Types...>::value || all_unsigned<Types...>::value >;
4006
4007 template<typename OfType, typename T>
4008 using never_out_of_range = std::integral_constant < bool,
4009 (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4010 || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4011
4012 template<typename OfType, typename T,
4013 bool OfTypeSigned = std::is_signed<OfType>::value,
4014 bool TSigned = std::is_signed<T>::value>
4016
4017 template<typename OfType, typename T>
4018 struct value_in_range_of_impl2<OfType, T, false, false>
4019 {
4020 static constexpr bool test(T val)
4021 {
4022 using CommonType = typename std::common_type<OfType, T>::type;
4023 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4024 }
4025 };
4026
4027 template<typename OfType, typename T>
4028 struct value_in_range_of_impl2<OfType, T, true, false>
4029 {
4030 static constexpr bool test(T val)
4031 {
4032 using CommonType = typename std::common_type<OfType, T>::type;
4033 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4034 }
4035 };
4036
4037 template<typename OfType, typename T>
4038 struct value_in_range_of_impl2<OfType, T, false, true>
4039 {
4040 static constexpr bool test(T val)
4041 {
4042 using CommonType = typename std::common_type<OfType, T>::type;
4043 return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4044 }
4045 };
4046
4047
4048 template<typename OfType, typename T>
4049 struct value_in_range_of_impl2<OfType, T, true, true>
4050 {
4051 static constexpr bool test(T val)
4052 {
4053 using CommonType = typename std::common_type<OfType, T>::type;
4054 return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4055 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4056 }
4057 };
4058
4059 template<typename OfType, typename T,
4060 bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4063
4064 template<typename OfType, typename T>
4065 struct value_in_range_of_impl1<OfType, T, false>
4066 {
4067 static constexpr bool test(T val)
4068 {
4070 }
4071 };
4072
4073 template<typename OfType, typename T>
4074 struct value_in_range_of_impl1<OfType, T, true>
4075 {
4076 static constexpr bool test(T /*val*/)
4077 {
4078 return true;
4079 }
4080 };
4081
4082 template<typename OfType, typename T>
4083 inline constexpr bool value_in_range_of(T val)
4084 {
4086 }
4087
4088 template<bool Value>
4089 using bool_constant = std::integral_constant<bool, Value>;
4090
4092 // is_c_string
4094
4095 namespace impl
4096 {
4097
4098 template<typename T>
4099 inline constexpr bool is_c_string()
4100 {
4101 using TUnExt = typename std::remove_extent<T>::type;
4102 using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4103 using TUnPtr = typename std::remove_pointer<T>::type;
4104 using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4105 return
4106 (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
4107 || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
4108 }
4109
4110 } // namespace impl
4111
4112 // checks whether T is a [cv] char */[cv] char[] C string
4113 template<typename T>
4114 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4115
4116 template<typename T>
4118
4120 // is_transparent
4122
4123 namespace impl
4124 {
4125
4126 template<typename T>
4127 inline constexpr bool is_transparent()
4128 {
4130 }
4131
4132 } // namespace impl
4133
4134 // checks whether T has a member named is_transparent
4135 template<typename T>
4136 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4137
4139
4140} // namespace detail
4142
4143// #include <nlohmann/detail/string_concat.hpp>
4144// __ _____ _____ _____
4145// __| | __| | | | JSON for Modern C++
4146// | | |__ | | | | | | version 3.11.2
4147// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4148//
4149// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4150// SPDX-License-Identifier: MIT
4151
4152
4153
4154#include <cstring> // strlen
4155#include <string> // string
4156#include <utility> // forward
4157
4158// #include <nlohmann/detail/meta/cpp_future.hpp>
4159
4160// #include <nlohmann/detail/meta/detected.hpp>
4161
4162
4164namespace detail
4165{
4166
4167 inline std::size_t concat_length()
4168 {
4169 return 0;
4170 }
4171
4172 template<typename... Args>
4173 inline std::size_t concat_length(const char* cstr, const Args& ... rest);
4174
4175 template<typename StringType, typename... Args>
4176 inline std::size_t concat_length(const StringType& str, const Args& ... rest);
4177
4178 template<typename... Args>
4179 inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
4180 {
4181 return 1 + concat_length(rest...);
4182 }
4183
4184 template<typename... Args>
4185 inline std::size_t concat_length(const char* cstr, const Args& ... rest)
4186 {
4187 // cppcheck-suppress ignoredReturnValue
4188 return ::strlen(cstr) + concat_length(rest...);
4189 }
4190
4191 template<typename StringType, typename... Args>
4192 inline std::size_t concat_length(const StringType& str, const Args& ... rest)
4193 {
4194 return str.size() + concat_length(rest...);
4195 }
4196
4197 template<typename OutStringType>
4198 inline void concat_into(OutStringType& /*out*/)
4199 {}
4200
4201 template<typename StringType, typename Arg>
4202 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg&& >()));
4203
4204 template<typename StringType, typename Arg>
4206
4207 template<typename StringType, typename Arg>
4208 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg&& >());
4209
4210 template<typename StringType, typename Arg>
4212
4213 template<typename StringType, typename Arg>
4214 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4215
4216 template<typename StringType, typename Arg>
4218
4219 template<typename StringType, typename Arg>
4220 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4221
4222 template<typename StringType, typename Arg>
4224
4225 template < typename OutStringType, typename Arg, typename... Args,
4226 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4228 inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest);
4229
4230 template < typename OutStringType, typename Arg, typename... Args,
4231 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4234 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4235
4236 template < typename OutStringType, typename Arg, typename... Args,
4237 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4241 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4242
4243 template<typename OutStringType, typename Arg, typename... Args,
4245 inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest)
4246 {
4247 out.append(std::forward<Arg>(arg));
4248 concat_into(out, std::forward<Args>(rest)...);
4249 }
4250
4251 template < typename OutStringType, typename Arg, typename... Args,
4252 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4253 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
4254 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4255 {
4256 out += std::forward<Arg>(arg);
4257 concat_into(out, std::forward<Args>(rest)...);
4258 }
4259
4260 template < typename OutStringType, typename Arg, typename... Args,
4261 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4262 && !detect_string_can_append_op<OutStringType, Arg>::value
4263 && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
4264 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4265 {
4266 out.append(arg.begin(), arg.end());
4267 concat_into(out, std::forward<Args>(rest)...);
4268 }
4269
4270 template < typename OutStringType, typename Arg, typename... Args,
4271 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4272 && !detect_string_can_append_op<OutStringType, Arg>::value
4273 && !detect_string_can_append_iter<OutStringType, Arg>::value
4274 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4275 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4276 {
4277 out.append(arg.data(), arg.size());
4278 concat_into(out, std::forward<Args>(rest)...);
4279 }
4280
4281 template<typename OutStringType = std::string, typename... Args>
4282 inline OutStringType concat(Args && ... args)
4283 {
4284 OutStringType str;
4285 str.reserve(concat_length(args...));
4286 concat_into(str, std::forward<Args>(args)...);
4287 return str;
4288 }
4289
4290} // namespace detail
4292
4293
4294
4296namespace detail
4297{
4298
4300 // exceptions //
4302
4305 class exception : public std::exception
4306 {
4307 public:
4309 const char* what() const noexcept override
4310 {
4311 return m.what();
4312 }
4313
4315 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4316
4317 protected:
4319 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4320
4321 static std::string name(const std::string& ename, int id_)
4322 {
4323 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4324 }
4325
4326 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4327 {
4328 return "";
4329 }
4330
4331 template<typename BasicJsonType>
4332 static std::string diagnostics(const BasicJsonType* leaf_element)
4333 {
4334#if JSON_DIAGNOSTICS
4335 std::vector<std::string> tokens;
4336 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4337 {
4338 switch (current->m_parent->type())
4339 {
4340 case value_t::array:
4341 {
4342 for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
4343 {
4344 if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
4345 {
4346 tokens.emplace_back(std::to_string(i));
4347 break;
4348 }
4349 }
4350 break;
4351 }
4352
4353 case value_t::object:
4354 {
4355 for (const auto& element : *current->m_parent->m_data.m_value.object)
4356 {
4357 if (&element.second == current)
4358 {
4359 tokens.emplace_back(element.first.c_str());
4360 break;
4361 }
4362 }
4363 break;
4364 }
4365
4366 case value_t::null: // LCOV_EXCL_LINE
4367 case value_t::string: // LCOV_EXCL_LINE
4368 case value_t::boolean: // LCOV_EXCL_LINE
4369 case value_t::number_integer: // LCOV_EXCL_LINE
4370 case value_t::number_unsigned: // LCOV_EXCL_LINE
4371 case value_t::number_float: // LCOV_EXCL_LINE
4372 case value_t::binary: // LCOV_EXCL_LINE
4373 case value_t::discarded: // LCOV_EXCL_LINE
4374 default: // LCOV_EXCL_LINE
4375 break; // LCOV_EXCL_LINE
4376 }
4377 }
4378
4379 if (tokens.empty())
4380 {
4381 return "";
4382 }
4383
4384 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4385 [](const std::string& a, const std::string& b)
4386 {
4387 return concat(a, '/', detail::escape(b));
4388 });
4389 return concat('(', str, ") ");
4390#else
4391 static_cast<void>(leaf_element);
4392 return "";
4393#endif
4394 }
4395
4396 private:
4398 std::runtime_error m;
4399 };
4400
4403 class parse_error : public exception
4404 {
4405 public:
4415 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4416 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4417 {
4418 const std::string w = concat(exception::name("parse_error", id_), "parse error",
4419 position_string(pos), ": ", exception::diagnostics(context), what_arg);
4420 return { id_, pos.chars_read_total, w.c_str() };
4421 }
4422
4423 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4424 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4425 {
4426 const std::string w = concat(exception::name("parse_error", id_), "parse error",
4427 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4428 ": ", exception::diagnostics(context), what_arg);
4429 return { id_, byte_, w.c_str() };
4430 }
4431
4441 const std::size_t byte;
4442
4443 private:
4444 parse_error(int id_, std::size_t byte_, const char* what_arg)
4445 : exception(id_, what_arg), byte(byte_) {}
4446
4447 static std::string position_string(const position_t& pos)
4448 {
4449 return concat(" at line ", std::to_string(pos.lines_read + 1),
4450 ", column ", std::to_string(pos.chars_read_current_line));
4451 }
4452 };
4453
4457 {
4458 public:
4459 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4460 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4461 {
4462 const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4463 return { id_, w.c_str() };
4464 }
4465
4466 private:
4468 invalid_iterator(int id_, const char* what_arg)
4469 : exception(id_, what_arg) {}
4470 };
4471
4474 class type_error : public exception
4475 {
4476 public:
4477 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4478 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4479 {
4480 const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4481 return { id_, w.c_str() };
4482 }
4483
4484 private:
4486 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4487 };
4488
4492 {
4493 public:
4494 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4495 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4496 {
4497 const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4498 return { id_, w.c_str() };
4499 }
4500
4501 private:
4503 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4504 };
4505
4508 class other_error : public exception
4509 {
4510 public:
4511 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4512 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4513 {
4514 const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4515 return { id_, w.c_str() };
4516 }
4517
4518 private:
4520 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4521 };
4522
4523} // namespace detail
4525
4526// #include <nlohmann/detail/macro_scope.hpp>
4527
4528// #include <nlohmann/detail/meta/cpp_future.hpp>
4529
4530// #include <nlohmann/detail/meta/identity_tag.hpp>
4531// __ _____ _____ _____
4532// __| | __| | | | JSON for Modern C++
4533// | | |__ | | | | | | version 3.11.2
4534// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4535//
4536// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4537// SPDX-License-Identifier: MIT
4538
4539
4540
4541// #include <nlohmann/detail/abi_macros.hpp>
4542
4543
4545namespace detail
4546{
4547
4548 // dispatching helper struct
4549 template <class T> struct identity_tag {};
4550
4551} // namespace detail
4553
4554// #include <nlohmann/detail/meta/std_fs.hpp>
4555// __ _____ _____ _____
4556// __| | __| | | | JSON for Modern C++
4557// | | |__ | | | | | | version 3.11.2
4558// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4559//
4560// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4561// SPDX-License-Identifier: MIT
4562
4563
4564
4565// #include <nlohmann/detail/macro_scope.hpp>
4566
4567
4568#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4569#include <experimental/filesystem>
4571namespace detail
4572{
4573 namespace std_fs = std::experimental::filesystem;
4574} // namespace detail
4576#elif JSON_HAS_FILESYSTEM
4577#include <filesystem>
4579namespace detail
4580{
4581 namespace std_fs = std::filesystem;
4582} // namespace detail
4584#endif
4585
4586// #include <nlohmann/detail/meta/type_traits.hpp>
4587
4588// #include <nlohmann/detail/string_concat.hpp>
4589
4590// #include <nlohmann/detail/value_t.hpp>
4591
4592
4594namespace detail
4595{
4596
4597 template<typename BasicJsonType>
4598 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4599 {
4600 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4601 {
4602 JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4603 }
4604 n = nullptr;
4605 }
4606
4607 // overloads for basic_json template parameters
4608 template < typename BasicJsonType, typename ArithmeticType,
4609 enable_if_t < std::is_arithmetic<ArithmeticType>::value &&
4610 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4611 int > = 0 >
4612 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4613 {
4614 switch (static_cast<value_t>(j))
4615 {
4617 {
4618 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4619 break;
4620 }
4622 {
4623 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4624 break;
4625 }
4627 {
4628 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4629 break;
4630 }
4631
4632 case value_t::null:
4633 case value_t::object:
4634 case value_t::array:
4635 case value_t::string:
4636 case value_t::boolean:
4637 case value_t::binary:
4638 case value_t::discarded:
4639 default:
4640 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4641 }
4642 }
4643
4644 template<typename BasicJsonType>
4645 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4646 {
4647 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4648 {
4649 JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4650 }
4651 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4652 }
4653
4654 template<typename BasicJsonType>
4655 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4656 {
4657 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4658 {
4659 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4660 }
4661 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4662 }
4663
4664 template <
4665 typename BasicJsonType, typename StringType,
4666 enable_if_t <
4667 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4668 && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4669 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4670 && !is_json_ref<StringType>::value, int > = 0 >
4671 inline void from_json(const BasicJsonType& j, StringType& s)
4672 {
4673 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4674 {
4675 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4676 }
4677
4678 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4679 }
4680
4681 template<typename BasicJsonType>
4682 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4683 {
4684 get_arithmetic_value(j, val);
4685 }
4686
4687 template<typename BasicJsonType>
4688 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4689 {
4690 get_arithmetic_value(j, val);
4691 }
4692
4693 template<typename BasicJsonType>
4694 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4695 {
4696 get_arithmetic_value(j, val);
4697 }
4698
4699#if !JSON_DISABLE_ENUM_SERIALIZATION
4700 template<typename BasicJsonType, typename EnumType,
4701 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4702 inline void from_json(const BasicJsonType& j, EnumType& e)
4703 {
4704 typename std::underlying_type<EnumType>::type val;
4705 get_arithmetic_value(j, val);
4706 e = static_cast<EnumType>(val);
4707 }
4708#endif // JSON_DISABLE_ENUM_SERIALIZATION
4709
4710 // forward_list doesn't have an insert method
4711 template<typename BasicJsonType, typename T, typename Allocator,
4712 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4713 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4714 {
4715 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4716 {
4717 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4718 }
4719 l.clear();
4720 std::transform(j.rbegin(), j.rend(),
4721 std::front_inserter(l), [](const BasicJsonType& i)
4722 {
4723 return i.template get<T>();
4724 });
4725 }
4726
4727 // valarray doesn't have an insert method
4728 template<typename BasicJsonType, typename T,
4729 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4730 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4731 {
4732 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4733 {
4734 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4735 }
4736 l.resize(j.size());
4737 std::transform(j.begin(), j.end(), std::begin(l),
4738 [](const BasicJsonType& elem)
4739 {
4740 return elem.template get<T>();
4741 });
4742 }
4743
4744 template<typename BasicJsonType, typename T, std::size_t N>
4745 auto from_json(const BasicJsonType& j, T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4746 -> decltype(j.template get<T>(), void())
4747 {
4748 for (std::size_t i = 0; i < N; ++i)
4749 {
4750 arr[i] = j.at(i).template get<T>();
4751 }
4752 }
4753
4754 template<typename BasicJsonType>
4755 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4756 {
4757 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4758 }
4759
4760 template<typename BasicJsonType, typename T, std::size_t N>
4761 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4762 priority_tag<2> /*unused*/)
4763 -> decltype(j.template get<T>(), void())
4764 {
4765 for (std::size_t i = 0; i < N; ++i)
4766 {
4767 arr[i] = j.at(i).template get<T>();
4768 }
4769 }
4770
4771 template<typename BasicJsonType, typename ConstructibleArrayType,
4773 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4774 int> = 0>
4775 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4776 -> decltype(
4777 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4778 j.template get<typename ConstructibleArrayType::value_type>(),
4779 void())
4780 {
4781 using std::end;
4782
4783 ConstructibleArrayType ret;
4784 ret.reserve(j.size());
4785 std::transform(j.begin(), j.end(),
4786 std::inserter(ret, end(ret)), [](const BasicJsonType& i)
4787 {
4788 // get<BasicJsonType>() returns *this, this won't call a from_json
4789 // method when value_type is BasicJsonType
4790 return i.template get<typename ConstructibleArrayType::value_type>();
4791 });
4792 arr = std::move(ret);
4793 }
4794
4795 template<typename BasicJsonType, typename ConstructibleArrayType,
4797 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4798 int> = 0>
4799 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4800 priority_tag<0> /*unused*/)
4801 {
4802 using std::end;
4803
4804 ConstructibleArrayType ret;
4805 std::transform(
4806 j.begin(), j.end(), std::inserter(ret, end(ret)),
4807 [](const BasicJsonType& i)
4808 {
4809 // get<BasicJsonType>() returns *this, this won't call a from_json
4810 // method when value_type is BasicJsonType
4811 return i.template get<typename ConstructibleArrayType::value_type>();
4812 });
4813 arr = std::move(ret);
4814 }
4815
4816 template < typename BasicJsonType, typename ConstructibleArrayType,
4817 enable_if_t <
4818 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value &&
4819 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
4821 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value &&
4822 !is_basic_json<ConstructibleArrayType>::value,
4823 int > = 0 >
4824 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4825 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4826 j.template get<typename ConstructibleArrayType::value_type>(),
4827 void())
4828 {
4829 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4830 {
4831 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4832 }
4833
4834 from_json_array_impl(j, arr, priority_tag<3> {});
4835 }
4836
4837 template < typename BasicJsonType, typename T, std::size_t... Idx >
4838 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4839 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4840 {
4841 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4842 }
4843
4844 template < typename BasicJsonType, typename T, std::size_t N >
4845 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4846 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4847 {
4848 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4849 {
4850 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4851 }
4852
4853 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4854 }
4855
4856 template<typename BasicJsonType>
4857 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4858 {
4859 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4860 {
4861 JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4862 }
4863
4864 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4865 }
4866
4867 template<typename BasicJsonType, typename ConstructibleObjectType,
4868 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4869 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4870 {
4871 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4872 {
4873 JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4874 }
4875
4876 ConstructibleObjectType ret;
4877 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4878 using value_type = typename ConstructibleObjectType::value_type;
4879 std::transform(
4880 inner_object->begin(), inner_object->end(),
4881 std::inserter(ret, ret.begin()),
4882 [](typename BasicJsonType::object_t::value_type const& p)
4883 {
4884 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4885 });
4886 obj = std::move(ret);
4887 }
4888
4889 // overload for arithmetic types, not chosen for basic_json template arguments
4890 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4891 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4892 // an arithmetic type?
4893 template < typename BasicJsonType, typename ArithmeticType,
4894 enable_if_t <
4895 std::is_arithmetic<ArithmeticType>::value &&
4896 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value &&
4897 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
4898 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
4899 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4900 int > = 0 >
4901 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4902 {
4903 switch (static_cast<value_t>(j))
4904 {
4906 {
4907 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4908 break;
4909 }
4911 {
4912 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4913 break;
4914 }
4916 {
4917 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4918 break;
4919 }
4920 case value_t::boolean:
4921 {
4922 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4923 break;
4924 }
4925
4926 case value_t::null:
4927 case value_t::object:
4928 case value_t::array:
4929 case value_t::string:
4930 case value_t::binary:
4931 case value_t::discarded:
4932 default:
4933 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4934 }
4935 }
4936
4937 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4938 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4939 {
4940 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4941 }
4942
4943 template < typename BasicJsonType, class A1, class A2 >
4944 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4945 {
4946 return { std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4947 std::forward<BasicJsonType>(j).at(1).template get<A2>() };
4948 }
4949
4950 template<typename BasicJsonType, typename A1, typename A2>
4951 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4952 {
4953 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4954 }
4955
4956 template<typename BasicJsonType, typename... Args>
4957 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4958 {
4959 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4960 }
4961
4962 template<typename BasicJsonType, typename... Args>
4963 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4964 {
4965 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4966 }
4967
4968 template<typename BasicJsonType, typename TupleRelated>
4969 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4970 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4971 {
4972 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4973 {
4974 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4975 }
4976
4977 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4978 }
4979
4980 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4981 typename = enable_if_t < !std::is_constructible <
4982 typename BasicJsonType::string_t, Key >::value >>
4983 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4984 {
4985 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4986 {
4987 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4988 }
4989 m.clear();
4990 for (const auto& p : j)
4991 {
4992 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4993 {
4994 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4995 }
4996 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4997 }
4998 }
4999
5000 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
5001 typename = enable_if_t < !std::is_constructible <
5002 typename BasicJsonType::string_t, Key >::value >>
5003 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
5004 {
5005 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5006 {
5007 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5008 }
5009 m.clear();
5010 for (const auto& p : j)
5011 {
5012 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5013 {
5014 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5015 }
5016 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5017 }
5018 }
5019
5020#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5021 template<typename BasicJsonType>
5022 inline void from_json(const BasicJsonType& j, std_fs::path& p)
5023 {
5024 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5025 {
5026 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5027 }
5028 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5029 }
5030#endif
5031
5033 {
5034 template<typename BasicJsonType, typename T>
5035 auto operator()(const BasicJsonType& j, T&& val) const
5036 noexcept(noexcept(from_json(j, std::forward<T>(val))))
5037 -> decltype(from_json(j, std::forward<T>(val)))
5038 {
5039 return from_json(j, std::forward<T>(val));
5040 }
5041 };
5042
5043} // namespace detail
5044
5045#ifndef JSON_HAS_CPP_17
5049namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5050{
5051#endif
5052 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5054#ifndef JSON_HAS_CPP_17
5055} // namespace
5056#endif
5057
5059
5060// #include <nlohmann/detail/conversions/to_json.hpp>
5061// __ _____ _____ _____
5062// __| | __| | | | JSON for Modern C++
5063// | | |__ | | | | | | version 3.11.2
5064// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5065//
5066// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5067// SPDX-License-Identifier: MIT
5068
5069
5070
5071#include <algorithm> // copy
5072#include <iterator> // begin, end
5073#include <string> // string
5074#include <tuple> // tuple, get
5075#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5076#include <utility> // move, forward, declval, pair
5077#include <valarray> // valarray
5078#include <vector> // vector
5079
5080// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5081// __ _____ _____ _____
5082// __| | __| | | | JSON for Modern C++
5083// | | |__ | | | | | | version 3.11.2
5084// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5085//
5086// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5087// SPDX-License-Identifier: MIT
5088
5089
5090
5091#include <cstddef> // size_t
5092#include <iterator> // input_iterator_tag
5093#include <string> // string, to_string
5094#include <tuple> // tuple_size, get, tuple_element
5095#include <utility> // move
5096
5097#if JSON_HAS_RANGES
5098#include <ranges> // enable_borrowed_range
5099#endif
5100
5101// #include <nlohmann/detail/abi_macros.hpp>
5102
5103// #include <nlohmann/detail/meta/type_traits.hpp>
5104
5105// #include <nlohmann/detail/value_t.hpp>
5106
5107
5109namespace detail
5110{
5111
5112 template<typename string_type>
5113 void int_to_string(string_type& target, std::size_t value)
5114 {
5115 // For ADL
5116 using std::to_string;
5117 target = to_string(value);
5118 }
5119 template<typename IteratorType> class iteration_proxy_value
5120 {
5121 public:
5122 using difference_type = std::ptrdiff_t;
5126 using iterator_category = std::input_iterator_tag;
5127 using string_type = typename std::remove_cv< typename std::remove_reference<decltype(std::declval<IteratorType>().key()) >::type >::type;
5128
5129 private:
5131 IteratorType anchor{};
5133 std::size_t array_index = 0;
5135 mutable std::size_t array_index_last = 0;
5137 mutable string_type array_index_str = "0";
5139 string_type empty_str{};
5140
5141 public:
5142 explicit iteration_proxy_value() = default;
5143 explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5144 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5145 && std::is_nothrow_default_constructible<string_type>::value)
5146 : anchor(std::move(it))
5147 , array_index(array_index_)
5148 {}
5149
5152 // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5154 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5155 && std::is_nothrow_move_constructible<string_type>::value) = default;
5157 noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5158 && std::is_nothrow_move_assignable<string_type>::value) = default;
5160
5162 const iteration_proxy_value& operator*() const
5163 {
5164 return *this;
5165 }
5166
5169 {
5170 ++anchor;
5171 ++array_index;
5172
5173 return *this;
5174 }
5175
5176 iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5177 {
5178 auto tmp = iteration_proxy_value(anchor, array_index);
5179 ++anchor;
5180 ++array_index;
5181 return tmp;
5182 }
5183
5186 {
5187 return anchor == o.anchor;
5188 }
5189
5192 {
5193 return anchor != o.anchor;
5194 }
5195
5197 const string_type& key() const
5198 {
5199 JSON_ASSERT(anchor.m_object != nullptr);
5200
5201 switch (anchor.m_object->type())
5202 {
5203 // use integer array index as key
5204 case value_t::array:
5205 {
5206 if (array_index != array_index_last)
5207 {
5208 int_to_string(array_index_str, array_index);
5209 array_index_last = array_index;
5210 }
5211 return array_index_str;
5212 }
5213
5214 // use key from the object
5215 case value_t::object:
5216 return anchor.key();
5217
5218 // use an empty key for all primitive types
5219 case value_t::null:
5220 case value_t::string:
5221 case value_t::boolean:
5225 case value_t::binary:
5226 case value_t::discarded:
5227 default:
5228 return empty_str;
5229 }
5230 }
5231
5233 typename IteratorType::reference value() const
5234 {
5235 return anchor.value();
5236 }
5237 };
5238
5240 template<typename IteratorType> class iteration_proxy
5241 {
5242 private:
5244 typename IteratorType::pointer container = nullptr;
5245
5246 public:
5247 explicit iteration_proxy() = default;
5248
5250 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5251 : container(&cont) {}
5252
5255 iteration_proxy(iteration_proxy&&) noexcept = default;
5256 iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5257 ~iteration_proxy() = default;
5258
5260 iteration_proxy_value<IteratorType> begin() const noexcept
5261 {
5262 return iteration_proxy_value<IteratorType>(container->begin());
5263 }
5264
5267 {
5268 return iteration_proxy_value<IteratorType>(container->end());
5269 }
5270 };
5271
5272 // Structured Bindings Support
5273 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5274 // And see https://github.com/nlohmann/json/pull/1391
5275 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5276 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5277 {
5278 return i.key();
5279 }
5280 // Structured Bindings Support
5281 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5282 // And see https://github.com/nlohmann/json/pull/1391
5283 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5284 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5285 {
5286 return i.value();
5287 }
5288
5289} // namespace detail
5291
5292// The Addition to the STD Namespace is required to add
5293// Structured Bindings Support to the iteration_proxy_value class
5294// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5295// And see https://github.com/nlohmann/json/pull/1391
5296namespace std
5297{
5298
5299#if defined(__clang__)
5300 // Fix: https://github.com/nlohmann/json/issues/1401
5301#pragma clang diagnostic push
5302#pragma clang diagnostic ignored "-Wmismatched-tags"
5303#endif
5304 template<typename IteratorType>
5305 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
5306 : public std::integral_constant<std::size_t, 2> {};
5307
5308 template<std::size_t N, typename IteratorType>
5309 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
5310 {
5311 public:
5312 using type = decltype(
5313 get<N>(std::declval <
5314 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5315 };
5316#if defined(__clang__)
5317#pragma clang diagnostic pop
5318#endif
5319
5320} // namespace std
5321
5322#if JSON_HAS_RANGES
5323template <typename IteratorType>
5324inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5325#endif
5326
5327// #include <nlohmann/detail/macro_scope.hpp>
5328
5329// #include <nlohmann/detail/meta/cpp_future.hpp>
5330
5331// #include <nlohmann/detail/meta/std_fs.hpp>
5332
5333// #include <nlohmann/detail/meta/type_traits.hpp>
5334
5335// #include <nlohmann/detail/value_t.hpp>
5336
5337
5339namespace detail
5340{
5341
5343 // constructors //
5345
5346 /*
5347 * Note all external_constructor<>::construct functions need to call
5348 * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
5349 * allocated value (e.g., a string). See bug issue
5350 * https://github.com/nlohmann/json/issues/2865 for more information.
5351 */
5352
5353 template<value_t> struct external_constructor;
5354
5355 template<>
5357 {
5358 template<typename BasicJsonType>
5359 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5360 {
5361 j.m_data.m_value.destroy(j.m_data.m_type);
5362 j.m_data.m_type = value_t::boolean;
5363 j.m_data.m_value = b;
5364 j.assert_invariant();
5365 }
5366 };
5367
5368 template<>
5370 {
5371 template<typename BasicJsonType>
5372 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5373 {
5374 j.m_data.m_value.destroy(j.m_data.m_type);
5375 j.m_data.m_type = value_t::string;
5376 j.m_data.m_value = s;
5377 j.assert_invariant();
5378 }
5379
5380 template<typename BasicJsonType>
5381 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5382 {
5383 j.m_data.m_value.destroy(j.m_data.m_type);
5384 j.m_data.m_type = value_t::string;
5385 j.m_data.m_value = std::move(s);
5386 j.assert_invariant();
5387 }
5388
5389 template < typename BasicJsonType, typename CompatibleStringType,
5390 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
5391 int > = 0 >
5392 static void construct(BasicJsonType& j, const CompatibleStringType& str)
5393 {
5394 j.m_data.m_value.destroy(j.m_data.m_type);
5395 j.m_data.m_type = value_t::string;
5396 j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5397 j.assert_invariant();
5398 }
5399 };
5400
5401 template<>
5403 {
5404 template<typename BasicJsonType>
5405 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5406 {
5407 j.m_data.m_value.destroy(j.m_data.m_type);
5408 j.m_data.m_type = value_t::binary;
5409 j.m_data.m_value = typename BasicJsonType::binary_t(b);
5410 j.assert_invariant();
5411 }
5412
5413 template<typename BasicJsonType>
5414 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5415 {
5416 j.m_data.m_value.destroy(j.m_data.m_type);
5417 j.m_data.m_type = value_t::binary;
5418 j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
5419 j.assert_invariant();
5420 }
5421 };
5422
5423 template<>
5425 {
5426 template<typename BasicJsonType>
5427 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5428 {
5429 j.m_data.m_value.destroy(j.m_data.m_type);
5430 j.m_data.m_type = value_t::number_float;
5431 j.m_data.m_value = val;
5432 j.assert_invariant();
5433 }
5434 };
5435
5436 template<>
5438 {
5439 template<typename BasicJsonType>
5440 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5441 {
5442 j.m_data.m_value.destroy(j.m_data.m_type);
5443 j.m_data.m_type = value_t::number_unsigned;
5444 j.m_data.m_value = val;
5445 j.assert_invariant();
5446 }
5447 };
5448
5449 template<>
5451 {
5452 template<typename BasicJsonType>
5453 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5454 {
5455 j.m_data.m_value.destroy(j.m_data.m_type);
5456 j.m_data.m_type = value_t::number_integer;
5457 j.m_data.m_value = val;
5458 j.assert_invariant();
5459 }
5460 };
5461
5462 template<>
5464 {
5465 template<typename BasicJsonType>
5466 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5467 {
5468 j.m_data.m_value.destroy(j.m_data.m_type);
5469 j.m_data.m_type = value_t::array;
5470 j.m_data.m_value = arr;
5471 j.set_parents();
5472 j.assert_invariant();
5473 }
5474
5475 template<typename BasicJsonType>
5476 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5477 {
5478 j.m_data.m_value.destroy(j.m_data.m_type);
5479 j.m_data.m_type = value_t::array;
5480 j.m_data.m_value = std::move(arr);
5481 j.set_parents();
5482 j.assert_invariant();
5483 }
5484
5485 template < typename BasicJsonType, typename CompatibleArrayType,
5486 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
5487 int > = 0 >
5488 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5489 {
5490 using std::begin;
5491 using std::end;
5492
5493 j.m_data.m_value.destroy(j.m_data.m_type);
5494 j.m_data.m_type = value_t::array;
5495 j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5496 j.set_parents();
5497 j.assert_invariant();
5498 }
5499
5500 template<typename BasicJsonType>
5501 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5502 {
5503 j.m_data.m_value.destroy(j.m_data.m_type);
5504 j.m_data.m_type = value_t::array;
5505 j.m_data.m_value = value_t::array;
5506 j.m_data.m_value.array->reserve(arr.size());
5507 for (const bool x : arr)
5508 {
5509 j.m_data.m_value.array->push_back(x);
5510 j.set_parent(j.m_data.m_value.array->back());
5511 }
5512 j.assert_invariant();
5513 }
5514
5515 template<typename BasicJsonType, typename T,
5517 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5518 {
5519 j.m_data.m_value.destroy(j.m_data.m_type);
5520 j.m_data.m_type = value_t::array;
5521 j.m_data.m_value = value_t::array;
5522 j.m_data.m_value.array->resize(arr.size());
5523 if (arr.size() > 0)
5524 {
5525 std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
5526 }
5527 j.set_parents();
5528 j.assert_invariant();
5529 }
5530 };
5531
5532 template<>
5534 {
5535 template<typename BasicJsonType>
5536 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5537 {
5538 j.m_data.m_value.destroy(j.m_data.m_type);
5539 j.m_data.m_type = value_t::object;
5540 j.m_data.m_value = obj;
5541 j.set_parents();
5542 j.assert_invariant();
5543 }
5544
5545 template<typename BasicJsonType>
5546 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5547 {
5548 j.m_data.m_value.destroy(j.m_data.m_type);
5549 j.m_data.m_type = value_t::object;
5550 j.m_data.m_value = std::move(obj);
5551 j.set_parents();
5552 j.assert_invariant();
5553 }
5554
5555 template < typename BasicJsonType, typename CompatibleObjectType,
5556 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
5557 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5558 {
5559 using std::begin;
5560 using std::end;
5561
5562 j.m_data.m_value.destroy(j.m_data.m_type);
5563 j.m_data.m_type = value_t::object;
5564 j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5565 j.set_parents();
5566 j.assert_invariant();
5567 }
5568 };
5569
5571 // to_json //
5573
5574 template<typename BasicJsonType, typename T,
5575 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5576 inline void to_json(BasicJsonType& j, T b) noexcept
5577 {
5579 }
5580
5581 template < typename BasicJsonType, typename BoolRef,
5582 enable_if_t <
5583 ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5584 && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5585 || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5586 && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5587 typename BasicJsonType::boolean_t >::value))
5588 && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
5589 inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5590 {
5591 external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5592 }
5593
5594 template<typename BasicJsonType, typename CompatibleString,
5595 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5596 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5597 {
5599 }
5600
5601 template<typename BasicJsonType>
5602 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5603 {
5605 }
5606
5607 template<typename BasicJsonType, typename FloatType,
5608 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5609 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5610 {
5611 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5612 }
5613
5614 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5615 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5616 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5617 {
5618 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5619 }
5620
5621 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5622 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5623 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5624 {
5625 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5626 }
5627
5628#if !JSON_DISABLE_ENUM_SERIALIZATION
5629 template<typename BasicJsonType, typename EnumType,
5630 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5631 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5632 {
5633 using underlying_type = typename std::underlying_type<EnumType>::type;
5634 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5635 }
5636#endif // JSON_DISABLE_ENUM_SERIALIZATION
5637
5638 template<typename BasicJsonType>
5639 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5640 {
5642 }
5643
5644 template < typename BasicJsonType, typename CompatibleArrayType,
5645 enable_if_t < is_compatible_array_type<BasicJsonType,
5646 CompatibleArrayType>::value &&
5647 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value &&
5649 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value &&
5650 !is_basic_json<CompatibleArrayType>::value,
5651 int > = 0 >
5652 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5653 {
5655 }
5656
5657 template<typename BasicJsonType>
5658 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5659 {
5661 }
5662
5663 template<typename BasicJsonType, typename T,
5664 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5665 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5666 {
5668 }
5669
5670 template<typename BasicJsonType>
5671 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5672 {
5674 }
5675
5676 template < typename BasicJsonType, typename CompatibleObjectType,
5677 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5678 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5679 {
5681 }
5682
5683 template<typename BasicJsonType>
5684 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5685 {
5687 }
5688
5689 template <
5690 typename BasicJsonType, typename T, std::size_t N,
5691 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5692 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5693 int > = 0 >
5694 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5695 {
5697 }
5698
5699 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5700 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5701 {
5702 j = { p.first, p.second };
5703 }
5704
5705 // for https://github.com/nlohmann/json/pull/1134
5706 template<typename BasicJsonType, typename T,
5707 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5708 inline void to_json(BasicJsonType& j, const T& b)
5709 {
5710 j = { {b.key(), b.value()} };
5711 }
5712
5713 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5714 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5715 {
5716 j = { std::get<Idx>(t)... };
5717 }
5718
5719 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5720 inline void to_json(BasicJsonType& j, const T& t)
5721 {
5722 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5723 }
5724
5725#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5726 template<typename BasicJsonType>
5727 inline void to_json(BasicJsonType& j, const std_fs::path& p)
5728 {
5729 j = p.string();
5730 }
5731#endif
5732
5734 {
5735 template<typename BasicJsonType, typename T>
5736 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5737 -> decltype(to_json(j, std::forward<T>(val)), void())
5738 {
5739 return to_json(j, std::forward<T>(val));
5740 }
5741 };
5742} // namespace detail
5743
5744#ifndef JSON_HAS_CPP_17
5748namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5749{
5750#endif
5751 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5753#ifndef JSON_HAS_CPP_17
5754} // namespace
5755#endif
5756
5758
5759// #include <nlohmann/detail/meta/identity_tag.hpp>
5760
5761
5763
5765template<typename ValueType, typename>
5767{
5770 template<typename BasicJsonType, typename TargetType = ValueType>
5771 static auto from_json(BasicJsonType&& j, TargetType& val) noexcept(
5772 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5773 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5774 {
5775 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5776 }
5777
5780 template<typename BasicJsonType, typename TargetType = ValueType>
5781 static auto from_json(BasicJsonType&& j) noexcept(
5782 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5783 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5784 {
5785 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5786 }
5787
5790 template<typename BasicJsonType, typename TargetType = ValueType>
5791 static auto to_json(BasicJsonType& j, TargetType&& val) noexcept(
5792 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5793 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5794 {
5795 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5796 }
5797};
5798
5800
5801// #include <nlohmann/byte_container_with_subtype.hpp>
5802// __ _____ _____ _____
5803// __| | __| | | | JSON for Modern C++
5804// | | |__ | | | | | | version 3.11.2
5805// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5806//
5807// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5808// SPDX-License-Identifier: MIT
5809
5810
5811
5812#include <cstdint> // uint8_t, uint64_t
5813#include <tuple> // tie
5814#include <utility> // move
5815
5816// #include <nlohmann/detail/abi_macros.hpp>
5817
5818
5820
5823template<typename BinaryType>
5824class byte_container_with_subtype : public BinaryType
5825{
5826public:
5827 using container_type = BinaryType;
5828 using subtype_type = std::uint64_t;
5829
5832 : container_type()
5833 {}
5834
5837 : container_type(b)
5838 {}
5839
5841 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5842 : container_type(std::move(b))
5843 {}
5844
5847 : container_type(b)
5848 , m_subtype(subtype_)
5849 , m_has_subtype(true)
5850 {}
5851
5853 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5854 : container_type(std::move(b))
5855 , m_subtype(subtype_)
5856 , m_has_subtype(true)
5857 {}
5858
5860 {
5861 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5862 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5863 }
5864
5866 {
5867 return !(rhs == *this);
5868 }
5869
5872 void set_subtype(subtype_type subtype_) noexcept
5873 {
5874 m_subtype = subtype_;
5875 m_has_subtype = true;
5876 }
5877
5880 constexpr subtype_type subtype() const noexcept
5881 {
5882 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5883 }
5884
5887 constexpr bool has_subtype() const noexcept
5888 {
5889 return m_has_subtype;
5890 }
5891
5894 void clear_subtype() noexcept
5895 {
5896 m_subtype = 0;
5897 m_has_subtype = false;
5898 }
5899
5900private:
5901 subtype_type m_subtype = 0;
5902 bool m_has_subtype = false;
5903};
5904
5906
5907// #include <nlohmann/detail/conversions/from_json.hpp>
5908
5909// #include <nlohmann/detail/conversions/to_json.hpp>
5910
5911// #include <nlohmann/detail/exceptions.hpp>
5912
5913// #include <nlohmann/detail/hash.hpp>
5914// __ _____ _____ _____
5915// __| | __| | | | JSON for Modern C++
5916// | | |__ | | | | | | version 3.11.2
5917// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5918//
5919// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5920// SPDX-License-Identifier: MIT
5921
5922
5923
5924#include <cstdint> // uint8_t
5925#include <cstddef> // size_t
5926#include <functional> // hash
5927
5928// #include <nlohmann/detail/abi_macros.hpp>
5929
5930// #include <nlohmann/detail/value_t.hpp>
5931
5932
5934namespace detail
5935{
5936
5937 // boost::hash_combine
5938 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5939 {
5940 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5941 return seed;
5942 }
5943
5955 template<typename BasicJsonType>
5956 std::size_t hash(const BasicJsonType& j)
5957 {
5958 using string_t = typename BasicJsonType::string_t;
5959 using number_integer_t = typename BasicJsonType::number_integer_t;
5960 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5961 using number_float_t = typename BasicJsonType::number_float_t;
5962
5963 const auto type = static_cast<std::size_t>(j.type());
5964 switch (j.type())
5965 {
5966 case BasicJsonType::value_t::null:
5967 case BasicJsonType::value_t::discarded:
5968 {
5969 return combine(type, 0);
5970 }
5971
5972 case BasicJsonType::value_t::object:
5973 {
5974 auto seed = combine(type, j.size());
5975 for (const auto& element : j.items())
5976 {
5977 const auto h = std::hash<string_t>{}(element.key());
5978 seed = combine(seed, h);
5979 seed = combine(seed, hash(element.value()));
5980 }
5981 return seed;
5982 }
5983
5984 case BasicJsonType::value_t::array:
5985 {
5986 auto seed = combine(type, j.size());
5987 for (const auto& element : j)
5988 {
5989 seed = combine(seed, hash(element));
5990 }
5991 return seed;
5992 }
5993
5994 case BasicJsonType::value_t::string:
5995 {
5996 const auto h = std::hash<string_t>{}(j.template get_ref<const string_t&>());
5997 return combine(type, h);
5998 }
5999
6000 case BasicJsonType::value_t::boolean:
6001 {
6002 const auto h = std::hash<bool>{}(j.template get<bool>());
6003 return combine(type, h);
6004 }
6005
6006 case BasicJsonType::value_t::number_integer:
6007 {
6008 const auto h = std::hash<number_integer_t>{}(j.template get<number_integer_t>());
6009 return combine(type, h);
6010 }
6011
6012 case BasicJsonType::value_t::number_unsigned:
6013 {
6014 const auto h = std::hash<number_unsigned_t>{}(j.template get<number_unsigned_t>());
6015 return combine(type, h);
6016 }
6017
6018 case BasicJsonType::value_t::number_float:
6019 {
6020 const auto h = std::hash<number_float_t>{}(j.template get<number_float_t>());
6021 return combine(type, h);
6022 }
6023
6024 case BasicJsonType::value_t::binary:
6025 {
6026 auto seed = combine(type, j.get_binary().size());
6027 const auto h = std::hash<bool>{}(j.get_binary().has_subtype());
6028 seed = combine(seed, h);
6029 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6030 for (const auto byte : j.get_binary())
6031 {
6032 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6033 }
6034 return seed;
6035 }
6036
6037 default: // LCOV_EXCL_LINE
6038 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6039 return 0; // LCOV_EXCL_LINE
6040 }
6041 }
6042
6043} // namespace detail
6045
6046// #include <nlohmann/detail/input/binary_reader.hpp>
6047// __ _____ _____ _____
6048// __| | __| | | | JSON for Modern C++
6049// | | |__ | | | | | | version 3.11.2
6050// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6051//
6052// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6053// SPDX-License-Identifier: MIT
6054
6055
6056
6057#include <algorithm> // generate_n
6058#include <array> // array
6059#include <cmath> // ldexp
6060#include <cstddef> // size_t
6061#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6062#include <cstdio> // snprintf
6063#include <cstring> // memcpy
6064#include <iterator> // back_inserter
6065#include <limits> // numeric_limits
6066#include <string> // char_traits, string
6067#include <utility> // make_pair, move
6068#include <vector> // vector
6069
6070// #include <nlohmann/detail/exceptions.hpp>
6071
6072// #include <nlohmann/detail/input/input_adapters.hpp>
6073// __ _____ _____ _____
6074// __| | __| | | | JSON for Modern C++
6075// | | |__ | | | | | | version 3.11.2
6076// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6077//
6078// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6079// SPDX-License-Identifier: MIT
6080
6081
6082
6083#include <array> // array
6084#include <cstddef> // size_t
6085#include <cstring> // strlen
6086#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6087#include <memory> // shared_ptr, make_shared, addressof
6088#include <numeric> // accumulate
6089#include <string> // string, char_traits
6090#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6091#include <utility> // pair, declval
6092
6093#ifndef JSON_NO_IO
6094#include <cstdio> // FILE *
6095#include <istream> // istream
6096#endif // JSON_NO_IO
6097
6098// #include <nlohmann/detail/iterators/iterator_traits.hpp>
6099
6100// #include <nlohmann/detail/macro_scope.hpp>
6101
6102
6104namespace detail
6105{
6106
6109
6111 // input adapters //
6113
6114#ifndef JSON_NO_IO
6120 {
6121 public:
6122 using char_type = char;
6123
6125 explicit file_input_adapter(std::FILE* f) noexcept
6126 : m_file(f)
6127 {
6128 JSON_ASSERT(m_file != nullptr);
6129 }
6130
6131 // make class move-only
6134 file_input_adapter& operator=(const file_input_adapter&) = delete;
6137
6138 std::char_traits<char>::int_type get_character() noexcept
6139 {
6140 return std::fgetc(m_file);
6141 }
6142
6143 private:
6145 std::FILE* m_file;
6146 };
6147
6148
6159 {
6160 public:
6161 using char_type = char;
6162
6164 {
6165 // clear stream flags; we use underlying streambuf I/O, do not
6166 // maintain ifstream flags, except eof
6167 if (is != nullptr)
6168 {
6169 is->clear(is->rdstate() & std::ios::eofbit);
6170 }
6171 }
6172
6173 explicit input_stream_adapter(std::istream& i)
6174 : is(&i), sb(i.rdbuf())
6175 {}
6176
6177 // delete because of pointer members
6181
6183 : is(rhs.is), sb(rhs.sb)
6184 {
6185 rhs.is = nullptr;
6186 rhs.sb = nullptr;
6187 }
6188
6189 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6190 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6191 // end up as the same value, e.g. 0xFFFFFFFF.
6192 std::char_traits<char>::int_type get_character()
6193 {
6194 auto res = sb->sbumpc();
6195 // set eof manually, as we don't use the istream interface.
6196 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6197 {
6198 is->clear(is->rdstate() | std::ios::eofbit);
6199 }
6200 return res;
6201 }
6202
6203 private:
6205 std::istream* is = nullptr;
6206 std::streambuf* sb = nullptr;
6207 };
6208#endif // JSON_NO_IO
6209
6210 // General-purpose iterator-based adapter. It might not be as fast as
6211 // theoretically possible for some containers, but it is extremely versatile.
6212 template<typename IteratorType>
6214 {
6215 public:
6216 using char_type = typename std::iterator_traits<IteratorType>::value_type;
6217
6218 iterator_input_adapter(IteratorType first, IteratorType last)
6219 : current(std::move(first)), end(std::move(last))
6220 {}
6221
6222 typename std::char_traits<char_type>::int_type get_character()
6223 {
6224 if (JSON_HEDLEY_LIKELY(current != end))
6225 {
6226 auto result = std::char_traits<char_type>::to_int_type(*current);
6227 std::advance(current, 1);
6228 return result;
6229 }
6230
6231 return std::char_traits<char_type>::eof();
6232 }
6233
6234 private:
6235 IteratorType current;
6236 IteratorType end;
6237
6238 template<typename BaseInputAdapter, size_t T>
6240
6241 bool empty() const
6242 {
6243 return current == end;
6244 }
6245 };
6246
6247
6248 template<typename BaseInputAdapter, size_t T>
6250
6251 template<typename BaseInputAdapter>
6252 struct wide_string_input_helper<BaseInputAdapter, 4>
6253 {
6254 // UTF-32
6255 static void fill_buffer(BaseInputAdapter& input,
6256 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6257 size_t& utf8_bytes_index,
6258 size_t& utf8_bytes_filled)
6259 {
6260 utf8_bytes_index = 0;
6261
6262 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6263 {
6264 utf8_bytes[0] = std::char_traits<char>::eof();
6265 utf8_bytes_filled = 1;
6266 }
6267 else
6268 {
6269 // get the current character
6270 const auto wc = input.get_character();
6271
6272 // UTF-32 to UTF-8 encoding
6273 if (wc < 0x80)
6274 {
6275 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6276 utf8_bytes_filled = 1;
6277 }
6278 else if (wc <= 0x7FF)
6279 {
6280 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6281 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6282 utf8_bytes_filled = 2;
6283 }
6284 else if (wc <= 0xFFFF)
6285 {
6286 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6287 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6288 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6289 utf8_bytes_filled = 3;
6290 }
6291 else if (wc <= 0x10FFFF)
6292 {
6293 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6294 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6295 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6296 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6297 utf8_bytes_filled = 4;
6298 }
6299 else
6300 {
6301 // unknown character
6302 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6303 utf8_bytes_filled = 1;
6304 }
6305 }
6306 }
6307 };
6308
6309 template<typename BaseInputAdapter>
6310 struct wide_string_input_helper<BaseInputAdapter, 2>
6311 {
6312 // UTF-16
6313 static void fill_buffer(BaseInputAdapter& input,
6314 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6315 size_t& utf8_bytes_index,
6316 size_t& utf8_bytes_filled)
6317 {
6318 utf8_bytes_index = 0;
6319
6320 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6321 {
6322 utf8_bytes[0] = std::char_traits<char>::eof();
6323 utf8_bytes_filled = 1;
6324 }
6325 else
6326 {
6327 // get the current character
6328 const auto wc = input.get_character();
6329
6330 // UTF-16 to UTF-8 encoding
6331 if (wc < 0x80)
6332 {
6333 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6334 utf8_bytes_filled = 1;
6335 }
6336 else if (wc <= 0x7FF)
6337 {
6338 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6339 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6340 utf8_bytes_filled = 2;
6341 }
6342 else if (0xD800 > wc || wc >= 0xE000)
6343 {
6344 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6345 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6346 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6347 utf8_bytes_filled = 3;
6348 }
6349 else
6350 {
6351 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6352 {
6353 const auto wc2 = static_cast<unsigned int>(input.get_character());
6354 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6355 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6356 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6357 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6358 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6359 utf8_bytes_filled = 4;
6360 }
6361 else
6362 {
6363 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6364 utf8_bytes_filled = 1;
6365 }
6366 }
6367 }
6368 }
6369 };
6370
6371 // Wraps another input apdater to convert wide character types into individual bytes.
6372 template<typename BaseInputAdapter, typename WideCharType>
6374 {
6375 public:
6376 using char_type = char;
6377
6378 wide_string_input_adapter(BaseInputAdapter base)
6379 : base_adapter(base) {}
6380
6381 typename std::char_traits<char>::int_type get_character() noexcept
6382 {
6383 // check if buffer needs to be filled
6384 if (utf8_bytes_index == utf8_bytes_filled)
6385 {
6386 fill_buffer<sizeof(WideCharType)>();
6387
6388 JSON_ASSERT(utf8_bytes_filled > 0);
6389 JSON_ASSERT(utf8_bytes_index == 0);
6390 }
6391
6392 // use buffer
6393 JSON_ASSERT(utf8_bytes_filled > 0);
6394 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
6395 return utf8_bytes[utf8_bytes_index++];
6396 }
6397
6398 private:
6399 BaseInputAdapter base_adapter;
6400
6401 template<size_t T>
6402 void fill_buffer()
6403 {
6404 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
6405 }
6406
6408 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = { {0, 0, 0, 0} };
6409
6411 std::size_t utf8_bytes_index = 0;
6413 std::size_t utf8_bytes_filled = 0;
6414 };
6415
6416
6417 template<typename IteratorType, typename Enable = void>
6419 {
6420 using iterator_type = IteratorType;
6421 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6423
6424 static adapter_type create(IteratorType first, IteratorType last)
6425 {
6426 return adapter_type(std::move(first), std::move(last));
6427 }
6428 };
6429
6430 template<typename T>
6432 {
6433 using value_type = typename std::iterator_traits<T>::value_type;
6434 enum
6435 {
6436 value = sizeof(value_type) > 1
6437 };
6438 };
6439
6440 template<typename IteratorType>
6442 {
6443 using iterator_type = IteratorType;
6444 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6447
6448 static adapter_type create(IteratorType first, IteratorType last)
6449 {
6450 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6451 }
6452 };
6453
6454 // General purpose iterator-based input
6455 template<typename IteratorType>
6457 {
6459 return factory_type::create(first, last);
6460 }
6461
6462 // Convenience shorthand from container to iterator
6463 // Enables ADL on begin(container) and end(container)
6464 // Encloses the using declarations in namespace for not to leak them to outside scope
6465
6466 namespace container_input_adapter_factory_impl
6467 {
6468
6469 using std::begin;
6470 using std::end;
6471
6472 template<typename ContainerType, typename Enable = void>
6474
6475 template<typename ContainerType>
6476 struct container_input_adapter_factory< ContainerType,
6477 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6478 {
6479 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6480
6481 static adapter_type create(const ContainerType& container)
6482 {
6483 return input_adapter(begin(container), end(container));
6484 }
6485 };
6486
6487 } // namespace container_input_adapter_factory_impl
6488
6489 template<typename ContainerType>
6491 {
6493 }
6494
6495#ifndef JSON_NO_IO
6496 // Special cases with fast paths
6497 inline file_input_adapter input_adapter(std::FILE* file)
6498 {
6499 return file_input_adapter(file);
6500 }
6501
6502 inline input_stream_adapter input_adapter(std::istream& stream)
6503 {
6504 return input_stream_adapter(stream);
6505 }
6506
6507 inline input_stream_adapter input_adapter(std::istream&& stream)
6508 {
6509 return input_stream_adapter(stream);
6510 }
6511#endif // JSON_NO_IO
6512
6513 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6514
6515 // Null-delimited strings, and the like.
6516 template < typename CharT,
6517 typename std::enable_if <
6518 std::is_pointer<CharT>::value &&
6519 !std::is_array<CharT>::value&&
6520 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6521 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6522 int >::type = 0 >
6524 {
6525 auto length = std::strlen(reinterpret_cast<const char*>(b));
6526 const auto* ptr = reinterpret_cast<const char*>(b);
6527 return input_adapter(ptr, ptr + length);
6528 }
6529
6530 template<typename T, std::size_t N>
6531 auto input_adapter(T(&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6532 {
6533 return input_adapter(array, array + N);
6534 }
6535
6536 // This class only handles inputs of input_buffer_adapter type.
6537 // It's required so that expressions like {ptr, len} can be implicitly cast
6538 // to the correct adapter.
6540 {
6541 public:
6542 template < typename CharT,
6543 typename std::enable_if <
6544 std::is_pointer<CharT>::value&&
6545 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6546 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6547 int >::type = 0 >
6548 span_input_adapter(CharT b, std::size_t l)
6549 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6550
6551 template<class IteratorType,
6552 typename std::enable_if<
6553 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6554 int>::type = 0>
6555 span_input_adapter(IteratorType first, IteratorType last)
6556 : ia(input_adapter(first, last)) {}
6557
6559 {
6560 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6561 }
6562
6563 private:
6565 };
6566
6567} // namespace detail
6569
6570// #include <nlohmann/detail/input/json_sax.hpp>
6571// __ _____ _____ _____
6572// __| | __| | | | JSON for Modern C++
6573// | | |__ | | | | | | version 3.11.2
6574// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6575//
6576// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6577// SPDX-License-Identifier: MIT
6578
6579
6580
6581#include <cstddef>
6582#include <string> // string
6583#include <utility> // move
6584#include <vector> // vector
6585
6586// #include <nlohmann/detail/exceptions.hpp>
6587
6588// #include <nlohmann/detail/macro_scope.hpp>
6589
6590// #include <nlohmann/detail/string_concat.hpp>
6591
6592
6594
6603template<typename BasicJsonType>
6605{
6606 using number_integer_t = typename BasicJsonType::number_integer_t;
6607 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6608 using number_float_t = typename BasicJsonType::number_float_t;
6609 using string_t = typename BasicJsonType::string_t;
6610 using binary_t = typename BasicJsonType::binary_t;
6611
6616 virtual bool null() = 0;
6617
6623 virtual bool boolean(bool val) = 0;
6624
6630 virtual bool number_integer(number_integer_t val) = 0;
6631
6637 virtual bool number_unsigned(number_unsigned_t val) = 0;
6638
6645 virtual bool number_float(number_float_t val, const string_t& s) = 0;
6646
6653 virtual bool string(string_t& val) = 0;
6654
6661 virtual bool binary(binary_t& val) = 0;
6662
6669 virtual bool start_object(std::size_t elements) = 0;
6670
6677 virtual bool key(string_t& val) = 0;
6678
6683 virtual bool end_object() = 0;
6684
6691 virtual bool start_array(std::size_t elements) = 0;
6692
6697 virtual bool end_array() = 0;
6698
6706 virtual bool parse_error(std::size_t position,
6707 const std::string& last_token,
6708 const detail::exception& ex) = 0;
6709
6710 json_sax() = default;
6711 json_sax(const json_sax&) = default;
6712 json_sax(json_sax&&) noexcept = default;
6713 json_sax& operator=(const json_sax&) = default;
6714 json_sax& operator=(json_sax&&) noexcept = default;
6715 virtual ~json_sax() = default;
6716};
6717
6718
6719namespace detail
6720{
6734 template<typename BasicJsonType>
6736 {
6737 public:
6738 using number_integer_t = typename BasicJsonType::number_integer_t;
6739 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6740 using number_float_t = typename BasicJsonType::number_float_t;
6741 using string_t = typename BasicJsonType::string_t;
6742 using binary_t = typename BasicJsonType::binary_t;
6743
6749 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6750 : root(r), allow_exceptions(allow_exceptions_)
6751 {}
6752
6753 // make class move-only
6755 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6757 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6759
6760 bool null()
6761 {
6762 handle_value(nullptr);
6763 return true;
6764 }
6765
6766 bool boolean(bool val)
6767 {
6768 handle_value(val);
6769 return true;
6770 }
6771
6773 {
6774 handle_value(val);
6775 return true;
6776 }
6777
6779 {
6780 handle_value(val);
6781 return true;
6782 }
6783
6784 bool number_float(number_float_t val, const string_t& /*unused*/)
6785 {
6786 handle_value(val);
6787 return true;
6788 }
6789
6790 bool string(string_t& val)
6791 {
6792 handle_value(val);
6793 return true;
6794 }
6795
6796 bool binary(binary_t& val)
6797 {
6798 handle_value(std::move(val));
6799 return true;
6800 }
6801
6802 bool start_object(std::size_t len)
6803 {
6804 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6805
6806 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6807 {
6808 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6809 }
6810
6811 return true;
6812 }
6813
6814 bool key(string_t& val)
6815 {
6816 JSON_ASSERT(!ref_stack.empty());
6817 JSON_ASSERT(ref_stack.back()->is_object());
6818
6819 // add null at given key and store the reference for later
6820 object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
6821 return true;
6822 }
6823
6825 {
6826 JSON_ASSERT(!ref_stack.empty());
6827 JSON_ASSERT(ref_stack.back()->is_object());
6828
6829 ref_stack.back()->set_parents();
6830 ref_stack.pop_back();
6831 return true;
6832 }
6833
6834 bool start_array(std::size_t len)
6835 {
6836 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6837
6838 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6839 {
6840 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6841 }
6842
6843 return true;
6844 }
6845
6847 {
6848 JSON_ASSERT(!ref_stack.empty());
6849 JSON_ASSERT(ref_stack.back()->is_array());
6850
6851 ref_stack.back()->set_parents();
6852 ref_stack.pop_back();
6853 return true;
6854 }
6855
6856 template<class Exception>
6857 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6858 const Exception& ex)
6859 {
6860 errored = true;
6861 static_cast<void>(ex);
6862 if (allow_exceptions)
6863 {
6864 JSON_THROW(ex);
6865 }
6866 return false;
6867 }
6868
6869 constexpr bool is_errored() const
6870 {
6871 return errored;
6872 }
6873
6874 private:
6881 template<typename Value>
6883 BasicJsonType* handle_value(Value&& v)
6884 {
6885 if (ref_stack.empty())
6886 {
6887 root = BasicJsonType(std::forward<Value>(v));
6888 return &root;
6889 }
6890
6891 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6892
6893 if (ref_stack.back()->is_array())
6894 {
6895 ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
6896 return &(ref_stack.back()->m_data.m_value.array->back());
6897 }
6898
6899 JSON_ASSERT(ref_stack.back()->is_object());
6900 JSON_ASSERT(object_element);
6901 *object_element = BasicJsonType(std::forward<Value>(v));
6902 return object_element;
6903 }
6904
6906 BasicJsonType& root;
6908 std::vector<BasicJsonType*> ref_stack{};
6910 BasicJsonType* object_element = nullptr;
6912 bool errored = false;
6914 const bool allow_exceptions = true;
6915 };
6916
6917 template<typename BasicJsonType>
6919 {
6920 public:
6921 using number_integer_t = typename BasicJsonType::number_integer_t;
6922 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6923 using number_float_t = typename BasicJsonType::number_float_t;
6924 using string_t = typename BasicJsonType::string_t;
6925 using binary_t = typename BasicJsonType::binary_t;
6926 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6927 using parse_event_t = typename BasicJsonType::parse_event_t;
6928
6930 const parser_callback_t cb,
6931 const bool allow_exceptions_ = true)
6932 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6933 {
6934 keep_stack.push_back(true);
6935 }
6936
6937 // make class move-only
6939 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6941 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6943
6944 bool null()
6945 {
6946 handle_value(nullptr);
6947 return true;
6948 }
6949
6950 bool boolean(bool val)
6951 {
6952 handle_value(val);
6953 return true;
6954 }
6955
6957 {
6958 handle_value(val);
6959 return true;
6960 }
6961
6963 {
6964 handle_value(val);
6965 return true;
6966 }
6967
6968 bool number_float(number_float_t val, const string_t& /*unused*/)
6969 {
6970 handle_value(val);
6971 return true;
6972 }
6973
6974 bool string(string_t& val)
6975 {
6976 handle_value(val);
6977 return true;
6978 }
6979
6980 bool binary(binary_t& val)
6981 {
6982 handle_value(std::move(val));
6983 return true;
6984 }
6985
6986 bool start_object(std::size_t len)
6987 {
6988 // check callback for object start
6989 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6990 keep_stack.push_back(keep);
6991
6992 auto val = handle_value(BasicJsonType::value_t::object, true);
6993 ref_stack.push_back(val.second);
6994
6995 // check object limit
6996 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6997 {
6998 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6999 }
7000
7001 return true;
7002 }
7003
7004 bool key(string_t& val)
7005 {
7006 BasicJsonType k = BasicJsonType(val);
7007
7008 // check callback for key
7009 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
7010 key_keep_stack.push_back(keep);
7011
7012 // add discarded value at given key and store the reference for later
7013 if (keep && ref_stack.back())
7014 {
7015 object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
7016 }
7017
7018 return true;
7019 }
7020
7022 {
7023 if (ref_stack.back())
7024 {
7025 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
7026 {
7027 // discard object
7028 *ref_stack.back() = discarded;
7029 }
7030 else
7031 {
7032 ref_stack.back()->set_parents();
7033 }
7034 }
7035
7036 JSON_ASSERT(!ref_stack.empty());
7037 JSON_ASSERT(!keep_stack.empty());
7038 ref_stack.pop_back();
7039 keep_stack.pop_back();
7040
7041 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
7042 {
7043 // remove discarded value
7044 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
7045 {
7046 if (it->is_discarded())
7047 {
7048 ref_stack.back()->erase(it);
7049 break;
7050 }
7051 }
7052 }
7053
7054 return true;
7055 }
7056
7057 bool start_array(std::size_t len)
7058 {
7059 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
7060 keep_stack.push_back(keep);
7061
7062 auto val = handle_value(BasicJsonType::value_t::array, true);
7063 ref_stack.push_back(val.second);
7064
7065 // check array limit
7066 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7067 {
7068 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
7069 }
7070
7071 return true;
7072 }
7073
7075 {
7076 bool keep = true;
7077
7078 if (ref_stack.back())
7079 {
7080 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
7081 if (keep)
7082 {
7083 ref_stack.back()->set_parents();
7084 }
7085 else
7086 {
7087 // discard array
7088 *ref_stack.back() = discarded;
7089 }
7090 }
7091
7092 JSON_ASSERT(!ref_stack.empty());
7093 JSON_ASSERT(!keep_stack.empty());
7094 ref_stack.pop_back();
7095 keep_stack.pop_back();
7096
7097 // remove discarded value
7098 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7099 {
7100 ref_stack.back()->m_data.m_value.array->pop_back();
7101 }
7102
7103 return true;
7104 }
7105
7106 template<class Exception>
7107 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7108 const Exception& ex)
7109 {
7110 errored = true;
7111 static_cast<void>(ex);
7112 if (allow_exceptions)
7113 {
7114 JSON_THROW(ex);
7115 }
7116 return false;
7117 }
7118
7119 constexpr bool is_errored() const
7120 {
7121 return errored;
7122 }
7123
7124 private:
7140 template<typename Value>
7141 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7142 {
7143 JSON_ASSERT(!keep_stack.empty());
7144
7145 // do not handle this value if we know it would be added to a discarded
7146 // container
7147 if (!keep_stack.back())
7148 {
7149 return { false, nullptr };
7150 }
7151
7152 // create value
7153 auto value = BasicJsonType(std::forward<Value>(v));
7154
7155 // check callback
7156 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7157
7158 // do not handle this value if we just learnt it shall be discarded
7159 if (!keep)
7160 {
7161 return { false, nullptr };
7162 }
7163
7164 if (ref_stack.empty())
7165 {
7166 root = std::move(value);
7167 return { true, &root };
7168 }
7169
7170 // skip this value if we already decided to skip the parent
7171 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7172 if (!ref_stack.back())
7173 {
7174 return { false, nullptr };
7175 }
7176
7177 // we now only expect arrays and objects
7178 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7179
7180 // array
7181 if (ref_stack.back()->is_array())
7182 {
7183 ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
7184 return { true, &(ref_stack.back()->m_data.m_value.array->back()) };
7185 }
7186
7187 // object
7188 JSON_ASSERT(ref_stack.back()->is_object());
7189 // check if we should store an element for the current key
7190 JSON_ASSERT(!key_keep_stack.empty());
7191 const bool store_element = key_keep_stack.back();
7192 key_keep_stack.pop_back();
7193
7194 if (!store_element)
7195 {
7196 return { false, nullptr };
7197 }
7198
7199 JSON_ASSERT(object_element);
7200 *object_element = std::move(value);
7201 return { true, object_element };
7202 }
7203
7205 BasicJsonType& root;
7207 std::vector<BasicJsonType*> ref_stack{};
7209 std::vector<bool> keep_stack{};
7211 std::vector<bool> key_keep_stack{};
7213 BasicJsonType* object_element = nullptr;
7215 bool errored = false;
7217 const parser_callback_t callback = nullptr;
7219 const bool allow_exceptions = true;
7221 BasicJsonType discarded = BasicJsonType::value_t::discarded;
7222 };
7223
7224 template<typename BasicJsonType>
7226 {
7227 public:
7228 using number_integer_t = typename BasicJsonType::number_integer_t;
7229 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7230 using number_float_t = typename BasicJsonType::number_float_t;
7231 using string_t = typename BasicJsonType::string_t;
7232 using binary_t = typename BasicJsonType::binary_t;
7233
7234 bool null()
7235 {
7236 return true;
7237 }
7238
7239 bool boolean(bool /*unused*/)
7240 {
7241 return true;
7242 }
7243
7245 {
7246 return true;
7247 }
7248
7250 {
7251 return true;
7252 }
7253
7254 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7255 {
7256 return true;
7257 }
7258
7259 bool string(string_t& /*unused*/)
7260 {
7261 return true;
7262 }
7263
7264 bool binary(binary_t& /*unused*/)
7265 {
7266 return true;
7267 }
7268
7269 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7270 {
7271 return true;
7272 }
7273
7274 bool key(string_t& /*unused*/)
7275 {
7276 return true;
7277 }
7278
7280 {
7281 return true;
7282 }
7283
7284 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7285 {
7286 return true;
7287 }
7288
7290 {
7291 return true;
7292 }
7293
7294 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7295 {
7296 return false;
7297 }
7298 };
7299
7300} // namespace detail
7302
7303// #include <nlohmann/detail/input/lexer.hpp>
7304// __ _____ _____ _____
7305// __| | __| | | | JSON for Modern C++
7306// | | |__ | | | | | | version 3.11.2
7307// |_____|_____|_____|_|___| https://github.com/nlohmann/json
7308//
7309// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7310// SPDX-License-Identifier: MIT
7311
7312
7313
7314#include <array> // array
7315#include <clocale> // localeconv
7316#include <cstddef> // size_t
7317#include <cstdio> // snprintf
7318#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7319#include <initializer_list> // initializer_list
7320#include <string> // char_traits, string
7321#include <utility> // move
7322#include <vector> // vector
7323
7324// #include <nlohmann/detail/input/input_adapters.hpp>
7325
7326// #include <nlohmann/detail/input/position_t.hpp>
7327
7328// #include <nlohmann/detail/macro_scope.hpp>
7329
7330
7332namespace detail
7333{
7334
7336 // lexer //
7338
7339 template<typename BasicJsonType>
7341 {
7342 public:
7344 enum class token_type
7345 {
7346 uninitialized,
7347 literal_true,
7348 literal_false,
7349 literal_null,
7350 value_string,
7351 value_unsigned,
7352 value_integer,
7353 value_float,
7354 begin_array,
7355 begin_object,
7356 end_array,
7357 end_object,
7358 name_separator,
7359 value_separator,
7360 parse_error,
7361 end_of_input,
7362 literal_or_value
7363 };
7364
7368 static const char* token_type_name(const token_type t) noexcept
7369 {
7370 switch (t)
7371 {
7372 case token_type::uninitialized:
7373 return "<uninitialized>";
7374 case token_type::literal_true:
7375 return "true literal";
7376 case token_type::literal_false:
7377 return "false literal";
7378 case token_type::literal_null:
7379 return "null literal";
7380 case token_type::value_string:
7381 return "string literal";
7382 case token_type::value_unsigned:
7383 case token_type::value_integer:
7384 case token_type::value_float:
7385 return "number literal";
7386 case token_type::begin_array:
7387 return "'['";
7388 case token_type::begin_object:
7389 return "'{'";
7390 case token_type::end_array:
7391 return "']'";
7392 case token_type::end_object:
7393 return "'}'";
7394 case token_type::name_separator:
7395 return "':'";
7396 case token_type::value_separator:
7397 return "','";
7398 case token_type::parse_error:
7399 return "<parse error>";
7400 case token_type::end_of_input:
7401 return "end of input";
7402 case token_type::literal_or_value:
7403 return "'[', '{', or a literal";
7404 // LCOV_EXCL_START
7405 default: // catch non-enum values
7406 return "unknown token";
7407 // LCOV_EXCL_STOP
7408 }
7409 }
7410 };
7416 template<typename BasicJsonType, typename InputAdapterType>
7417 class lexer : public lexer_base<BasicJsonType>
7418 {
7419 using number_integer_t = typename BasicJsonType::number_integer_t;
7420 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7421 using number_float_t = typename BasicJsonType::number_float_t;
7422 using string_t = typename BasicJsonType::string_t;
7423 using char_type = typename InputAdapterType::char_type;
7424 using char_int_type = typename std::char_traits<char_type>::int_type;
7425
7426 public:
7428
7429 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7430 : ia(std::move(adapter))
7431 , ignore_comments(ignore_comments_)
7432 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7433 {}
7434
7435 // delete because of pointer members
7436 lexer(const lexer&) = delete;
7437 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7438 lexer& operator=(lexer&) = delete;
7439 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7440 ~lexer() = default;
7441
7442 private:
7444 // locales
7446
7449 static char get_decimal_point() noexcept
7450 {
7451 const auto* loc = localeconv();
7452 JSON_ASSERT(loc != nullptr);
7453 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7454 }
7455
7457 // scan functions
7459
7475 int get_codepoint()
7476 {
7477 // this function only makes sense after reading `\u`
7478 JSON_ASSERT(current == 'u');
7479 int codepoint = 0;
7480
7481 const auto factors = { 12u, 8u, 4u, 0u };
7482 for (const auto factor : factors)
7483 {
7484 get();
7485
7486 if (current >= '0' && current <= '9')
7487 {
7488 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7489 }
7490 else if (current >= 'A' && current <= 'F')
7491 {
7492 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7493 }
7494 else if (current >= 'a' && current <= 'f')
7495 {
7496 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7497 }
7498 else
7499 {
7500 return -1;
7501 }
7502 }
7503
7504 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7505 return codepoint;
7506 }
7507
7523 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7524 {
7525 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7526 add(current);
7527
7528 for (auto range = ranges.begin(); range != ranges.end(); ++range)
7529 {
7530 get();
7531 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
7532 {
7533 add(current);
7534 }
7535 else
7536 {
7537 error_message = "invalid string: ill-formed UTF-8 byte";
7538 return false;
7539 }
7540 }
7541
7542 return true;
7543 }
7544
7560 token_type scan_string()
7561 {
7562 // reset token_buffer (ignore opening quote)
7563 reset();
7564
7565 // we entered the function by reading an open quote
7566 JSON_ASSERT(current == '\"');
7567
7568 while (true)
7569 {
7570 // get next character
7571 switch (get())
7572 {
7573 // end of file while parsing string
7574 case std::char_traits<char_type>::eof():
7575 {
7576 error_message = "invalid string: missing closing quote";
7577 return token_type::parse_error;
7578 }
7579
7580 // closing quote
7581 case '\"':
7582 {
7583 return token_type::value_string;
7584 }
7585
7586 // escapes
7587 case '\\':
7588 {
7589 switch (get())
7590 {
7591 // quotation mark
7592 case '\"':
7593 add('\"');
7594 break;
7595 // reverse solidus
7596 case '\\':
7597 add('\\');
7598 break;
7599 // solidus
7600 case '/':
7601 add('/');
7602 break;
7603 // backspace
7604 case 'b':
7605 add('\b');
7606 break;
7607 // form feed
7608 case 'f':
7609 add('\f');
7610 break;
7611 // line feed
7612 case 'n':
7613 add('\n');
7614 break;
7615 // carriage return
7616 case 'r':
7617 add('\r');
7618 break;
7619 // tab
7620 case 't':
7621 add('\t');
7622 break;
7623
7624 // unicode escapes
7625 case 'u':
7626 {
7627 const int codepoint1 = get_codepoint();
7628 int codepoint = codepoint1; // start with codepoint1
7629
7630 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7631 {
7632 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7633 return token_type::parse_error;
7634 }
7635
7636 // check if code point is a high surrogate
7637 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7638 {
7639 // expect next \uxxxx entry
7640 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7641 {
7642 const int codepoint2 = get_codepoint();
7643
7644 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7645 {
7646 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7647 return token_type::parse_error;
7648 }
7649
7650 // check if codepoint2 is a low surrogate
7651 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7652 {
7653 // overwrite codepoint
7654 codepoint = static_cast<int>(
7655 // high surrogate occupies the most significant 22 bits
7656 (static_cast<unsigned int>(codepoint1) << 10u)
7657 // low surrogate occupies the least significant 15 bits
7658 + static_cast<unsigned int>(codepoint2)
7659 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7660 // in the result, so we have to subtract with:
7661 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7662 -0x35FDC00u);
7663 }
7664 else
7665 {
7666 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7667 return token_type::parse_error;
7668 }
7669 }
7670 else
7671 {
7672 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7673 return token_type::parse_error;
7674 }
7675 }
7676 else
7677 {
7678 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7679 {
7680 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7681 return token_type::parse_error;
7682 }
7683 }
7684
7685 // result of the above calculation yields a proper codepoint
7686 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7687
7688 // translate codepoint into bytes
7689 if (codepoint < 0x80)
7690 {
7691 // 1-byte characters: 0xxxxxxx (ASCII)
7692 add(static_cast<char_int_type>(codepoint));
7693 }
7694 else if (codepoint <= 0x7FF)
7695 {
7696 // 2-byte characters: 110xxxxx 10xxxxxx
7697 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7698 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7699 }
7700 else if (codepoint <= 0xFFFF)
7701 {
7702 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7703 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7704 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7705 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7706 }
7707 else
7708 {
7709 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7710 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7711 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7712 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7713 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7714 }
7715
7716 break;
7717 }
7718
7719 // other characters after escape
7720 default:
7721 error_message = "invalid string: forbidden character after backslash";
7722 return token_type::parse_error;
7723 }
7724
7725 break;
7726 }
7727
7728 // invalid control characters
7729 case 0x00:
7730 {
7731 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7732 return token_type::parse_error;
7733 }
7734
7735 case 0x01:
7736 {
7737 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7738 return token_type::parse_error;
7739 }
7740
7741 case 0x02:
7742 {
7743 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7744 return token_type::parse_error;
7745 }
7746
7747 case 0x03:
7748 {
7749 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7750 return token_type::parse_error;
7751 }
7752
7753 case 0x04:
7754 {
7755 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7756 return token_type::parse_error;
7757 }
7758
7759 case 0x05:
7760 {
7761 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7762 return token_type::parse_error;
7763 }
7764
7765 case 0x06:
7766 {
7767 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7768 return token_type::parse_error;
7769 }
7770
7771 case 0x07:
7772 {
7773 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7774 return token_type::parse_error;
7775 }
7776
7777 case 0x08:
7778 {
7779 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7780 return token_type::parse_error;
7781 }
7782
7783 case 0x09:
7784 {
7785 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7786 return token_type::parse_error;
7787 }
7788
7789 case 0x0A:
7790 {
7791 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7792 return token_type::parse_error;
7793 }
7794
7795 case 0x0B:
7796 {
7797 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7798 return token_type::parse_error;
7799 }
7800
7801 case 0x0C:
7802 {
7803 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7804 return token_type::parse_error;
7805 }
7806
7807 case 0x0D:
7808 {
7809 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7810 return token_type::parse_error;
7811 }
7812
7813 case 0x0E:
7814 {
7815 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7816 return token_type::parse_error;
7817 }
7818
7819 case 0x0F:
7820 {
7821 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7822 return token_type::parse_error;
7823 }
7824
7825 case 0x10:
7826 {
7827 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7828 return token_type::parse_error;
7829 }
7830
7831 case 0x11:
7832 {
7833 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7834 return token_type::parse_error;
7835 }
7836
7837 case 0x12:
7838 {
7839 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7840 return token_type::parse_error;
7841 }
7842
7843 case 0x13:
7844 {
7845 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7846 return token_type::parse_error;
7847 }
7848
7849 case 0x14:
7850 {
7851 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7852 return token_type::parse_error;
7853 }
7854
7855 case 0x15:
7856 {
7857 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7858 return token_type::parse_error;
7859 }
7860
7861 case 0x16:
7862 {
7863 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7864 return token_type::parse_error;
7865 }
7866
7867 case 0x17:
7868 {
7869 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7870 return token_type::parse_error;
7871 }
7872
7873 case 0x18:
7874 {
7875 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7876 return token_type::parse_error;
7877 }
7878
7879 case 0x19:
7880 {
7881 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7882 return token_type::parse_error;
7883 }
7884
7885 case 0x1A:
7886 {
7887 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7888 return token_type::parse_error;
7889 }
7890
7891 case 0x1B:
7892 {
7893 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7894 return token_type::parse_error;
7895 }
7896
7897 case 0x1C:
7898 {
7899 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7900 return token_type::parse_error;
7901 }
7902
7903 case 0x1D:
7904 {
7905 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7906 return token_type::parse_error;
7907 }
7908
7909 case 0x1E:
7910 {
7911 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7912 return token_type::parse_error;
7913 }
7914
7915 case 0x1F:
7916 {
7917 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7918 return token_type::parse_error;
7919 }
7920
7921 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7922 case 0x20:
7923 case 0x21:
7924 case 0x23:
7925 case 0x24:
7926 case 0x25:
7927 case 0x26:
7928 case 0x27:
7929 case 0x28:
7930 case 0x29:
7931 case 0x2A:
7932 case 0x2B:
7933 case 0x2C:
7934 case 0x2D:
7935 case 0x2E:
7936 case 0x2F:
7937 case 0x30:
7938 case 0x31:
7939 case 0x32:
7940 case 0x33:
7941 case 0x34:
7942 case 0x35:
7943 case 0x36:
7944 case 0x37:
7945 case 0x38:
7946 case 0x39:
7947 case 0x3A:
7948 case 0x3B:
7949 case 0x3C:
7950 case 0x3D:
7951 case 0x3E:
7952 case 0x3F:
7953 case 0x40:
7954 case 0x41:
7955 case 0x42:
7956 case 0x43:
7957 case 0x44:
7958 case 0x45:
7959 case 0x46:
7960 case 0x47:
7961 case 0x48:
7962 case 0x49:
7963 case 0x4A:
7964 case 0x4B:
7965 case 0x4C:
7966 case 0x4D:
7967 case 0x4E:
7968 case 0x4F:
7969 case 0x50:
7970 case 0x51:
7971 case 0x52:
7972 case 0x53:
7973 case 0x54:
7974 case 0x55:
7975 case 0x56:
7976 case 0x57:
7977 case 0x58:
7978 case 0x59:
7979 case 0x5A:
7980 case 0x5B:
7981 case 0x5D:
7982 case 0x5E:
7983 case 0x5F:
7984 case 0x60:
7985 case 0x61:
7986 case 0x62:
7987 case 0x63:
7988 case 0x64:
7989 case 0x65:
7990 case 0x66:
7991 case 0x67:
7992 case 0x68:
7993 case 0x69:
7994 case 0x6A:
7995 case 0x6B:
7996 case 0x6C:
7997 case 0x6D:
7998 case 0x6E:
7999 case 0x6F:
8000 case 0x70:
8001 case 0x71:
8002 case 0x72:
8003 case 0x73:
8004 case 0x74:
8005 case 0x75:
8006 case 0x76:
8007 case 0x77:
8008 case 0x78:
8009 case 0x79:
8010 case 0x7A:
8011 case 0x7B:
8012 case 0x7C:
8013 case 0x7D:
8014 case 0x7E:
8015 case 0x7F:
8016 {
8017 add(current);
8018 break;
8019 }
8020
8021 // U+0080..U+07FF: bytes C2..DF 80..BF
8022 case 0xC2:
8023 case 0xC3:
8024 case 0xC4:
8025 case 0xC5:
8026 case 0xC6:
8027 case 0xC7:
8028 case 0xC8:
8029 case 0xC9:
8030 case 0xCA:
8031 case 0xCB:
8032 case 0xCC:
8033 case 0xCD:
8034 case 0xCE:
8035 case 0xCF:
8036 case 0xD0:
8037 case 0xD1:
8038 case 0xD2:
8039 case 0xD3:
8040 case 0xD4:
8041 case 0xD5:
8042 case 0xD6:
8043 case 0xD7:
8044 case 0xD8:
8045 case 0xD9:
8046 case 0xDA:
8047 case 0xDB:
8048 case 0xDC:
8049 case 0xDD:
8050 case 0xDE:
8051 case 0xDF:
8052 {
8053 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({ 0x80, 0xBF })))
8054 {
8055 return token_type::parse_error;
8056 }
8057 break;
8058 }
8059
8060 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8061 case 0xE0:
8062 {
8063 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0xA0, 0xBF, 0x80, 0xBF }))))
8064 {
8065 return token_type::parse_error;
8066 }
8067 break;
8068 }
8069
8070 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8071 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8072 case 0xE1:
8073 case 0xE2:
8074 case 0xE3:
8075 case 0xE4:
8076 case 0xE5:
8077 case 0xE6:
8078 case 0xE7:
8079 case 0xE8:
8080 case 0xE9:
8081 case 0xEA:
8082 case 0xEB:
8083 case 0xEC:
8084 case 0xEE:
8085 case 0xEF:
8086 {
8087 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF }))))
8088 {
8089 return token_type::parse_error;
8090 }
8091 break;
8092 }
8093
8094 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8095 case 0xED:
8096 {
8097 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x9F, 0x80, 0xBF }))))
8098 {
8099 return token_type::parse_error;
8100 }
8101 break;
8102 }
8103
8104 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8105 case 0xF0:
8106 {
8107 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
8108 {
8109 return token_type::parse_error;
8110 }
8111 break;
8112 }
8113
8114 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8115 case 0xF1:
8116 case 0xF2:
8117 case 0xF3:
8118 {
8119 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
8120 {
8121 return token_type::parse_error;
8122 }
8123 break;
8124 }
8125
8126 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8127 case 0xF4:
8128 {
8129 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF }))))
8130 {
8131 return token_type::parse_error;
8132 }
8133 break;
8134 }
8135
8136 // remaining bytes (80..C1 and F5..FF) are ill-formed
8137 default:
8138 {
8139 error_message = "invalid string: ill-formed UTF-8 byte";
8140 return token_type::parse_error;
8141 }
8142 }
8143 }
8144 }
8145
8150 bool scan_comment()
8151 {
8152 switch (get())
8153 {
8154 // single-line comments skip input until a newline or EOF is read
8155 case '/':
8156 {
8157 while (true)
8158 {
8159 switch (get())
8160 {
8161 case '\n':
8162 case '\r':
8163 case std::char_traits<char_type>::eof():
8164 case '\0':
8165 return true;
8166
8167 default:
8168 break;
8169 }
8170 }
8171 }
8172
8173 // multi-line comments skip input until */ is read
8174 case '*':
8175 {
8176 while (true)
8177 {
8178 switch (get())
8179 {
8180 case std::char_traits<char_type>::eof():
8181 case '\0':
8182 {
8183 error_message = "invalid comment; missing closing '*/'";
8184 return false;
8185 }
8186
8187 case '*':
8188 {
8189 switch (get())
8190 {
8191 case '/':
8192 return true;
8193
8194 default:
8195 {
8196 unget();
8197 continue;
8198 }
8199 }
8200 }
8201
8202 default:
8203 continue;
8204 }
8205 }
8206 }
8207
8208 // unexpected character after reading '/'
8209 default:
8210 {
8211 error_message = "invalid comment; expecting '/' or '*' after '/'";
8212 return false;
8213 }
8214 }
8215 }
8216
8218 static void strtof(float& f, const char* str, char** endptr) noexcept
8219 {
8220 f = std::strtof(str, endptr);
8221 }
8222
8224 static void strtof(double& f, const char* str, char** endptr) noexcept
8225 {
8226 f = std::strtod(str, endptr);
8227 }
8228
8230 static void strtof(long double& f, const char* str, char** endptr) noexcept
8231 {
8232 f = std::strtold(str, endptr);
8233 }
8234
8275 token_type scan_number() // lgtm [cpp/use-of-goto]
8276 {
8277 // reset token_buffer to store the number's bytes
8278 reset();
8279
8280 // the type of the parsed number; initially set to unsigned; will be
8281 // changed if minus sign, decimal point or exponent is read
8282 token_type number_type = token_type::value_unsigned;
8283
8284 // state (init): we just found out we need to scan a number
8285 switch (current)
8286 {
8287 case '-':
8288 {
8289 add(current);
8290 goto scan_number_minus;
8291 }
8292
8293 case '0':
8294 {
8295 add(current);
8296 goto scan_number_zero;
8297 }
8298
8299 case '1':
8300 case '2':
8301 case '3':
8302 case '4':
8303 case '5':
8304 case '6':
8305 case '7':
8306 case '8':
8307 case '9':
8308 {
8309 add(current);
8310 goto scan_number_any1;
8311 }
8312
8313 // all other characters are rejected outside scan_number()
8314 default: // LCOV_EXCL_LINE
8315 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8316 }
8317
8318 scan_number_minus:
8319 // state: we just parsed a leading minus sign
8320 number_type = token_type::value_integer;
8321 switch (get())
8322 {
8323 case '0':
8324 {
8325 add(current);
8326 goto scan_number_zero;
8327 }
8328
8329 case '1':
8330 case '2':
8331 case '3':
8332 case '4':
8333 case '5':
8334 case '6':
8335 case '7':
8336 case '8':
8337 case '9':
8338 {
8339 add(current);
8340 goto scan_number_any1;
8341 }
8342
8343 default:
8344 {
8345 error_message = "invalid number; expected digit after '-'";
8346 return token_type::parse_error;
8347 }
8348 }
8349
8350 scan_number_zero:
8351 // state: we just parse a zero (maybe with a leading minus sign)
8352 switch (get())
8353 {
8354 case '.':
8355 {
8356 add(decimal_point_char);
8357 goto scan_number_decimal1;
8358 }
8359
8360 case 'e':
8361 case 'E':
8362 {
8363 add(current);
8364 goto scan_number_exponent;
8365 }
8366
8367 default:
8368 goto scan_number_done;
8369 }
8370
8371 scan_number_any1:
8372 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8373 switch (get())
8374 {
8375 case '0':
8376 case '1':
8377 case '2':
8378 case '3':
8379 case '4':
8380 case '5':
8381 case '6':
8382 case '7':
8383 case '8':
8384 case '9':
8385 {
8386 add(current);
8387 goto scan_number_any1;
8388 }
8389
8390 case '.':
8391 {
8392 add(decimal_point_char);
8393 goto scan_number_decimal1;
8394 }
8395
8396 case 'e':
8397 case 'E':
8398 {
8399 add(current);
8400 goto scan_number_exponent;
8401 }
8402
8403 default:
8404 goto scan_number_done;
8405 }
8406
8407 scan_number_decimal1:
8408 // state: we just parsed a decimal point
8409 number_type = token_type::value_float;
8410 switch (get())
8411 {
8412 case '0':
8413 case '1':
8414 case '2':
8415 case '3':
8416 case '4':
8417 case '5':
8418 case '6':
8419 case '7':
8420 case '8':
8421 case '9':
8422 {
8423 add(current);
8424 goto scan_number_decimal2;
8425 }
8426
8427 default:
8428 {
8429 error_message = "invalid number; expected digit after '.'";
8430 return token_type::parse_error;
8431 }
8432 }
8433
8434 scan_number_decimal2:
8435 // we just parsed at least one number after a decimal point
8436 switch (get())
8437 {
8438 case '0':
8439 case '1':
8440 case '2':
8441 case '3':
8442 case '4':
8443 case '5':
8444 case '6':
8445 case '7':
8446 case '8':
8447 case '9':
8448 {
8449 add(current);
8450 goto scan_number_decimal2;
8451 }
8452
8453 case 'e':
8454 case 'E':
8455 {
8456 add(current);
8457 goto scan_number_exponent;
8458 }
8459
8460 default:
8461 goto scan_number_done;
8462 }
8463
8464 scan_number_exponent:
8465 // we just parsed an exponent
8466 number_type = token_type::value_float;
8467 switch (get())
8468 {
8469 case '+':
8470 case '-':
8471 {
8472 add(current);
8473 goto scan_number_sign;
8474 }
8475
8476 case '0':
8477 case '1':
8478 case '2':
8479 case '3':
8480 case '4':
8481 case '5':
8482 case '6':
8483 case '7':
8484 case '8':
8485 case '9':
8486 {
8487 add(current);
8488 goto scan_number_any2;
8489 }
8490
8491 default:
8492 {
8493 error_message =
8494 "invalid number; expected '+', '-', or digit after exponent";
8495 return token_type::parse_error;
8496 }
8497 }
8498
8499 scan_number_sign:
8500 // we just parsed an exponent sign
8501 switch (get())
8502 {
8503 case '0':
8504 case '1':
8505 case '2':
8506 case '3':
8507 case '4':
8508 case '5':
8509 case '6':
8510 case '7':
8511 case '8':
8512 case '9':
8513 {
8514 add(current);
8515 goto scan_number_any2;
8516 }
8517
8518 default:
8519 {
8520 error_message = "invalid number; expected digit after exponent sign";
8521 return token_type::parse_error;
8522 }
8523 }
8524
8525 scan_number_any2:
8526 // we just parsed a number after the exponent or exponent sign
8527 switch (get())
8528 {
8529 case '0':
8530 case '1':
8531 case '2':
8532 case '3':
8533 case '4':
8534 case '5':
8535 case '6':
8536 case '7':
8537 case '8':
8538 case '9':
8539 {
8540 add(current);
8541 goto scan_number_any2;
8542 }
8543
8544 default:
8545 goto scan_number_done;
8546 }
8547
8548 scan_number_done:
8549 // unget the character after the number (we only read it to know that
8550 // we are done scanning a number)
8551 unget();
8552
8553 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8554 errno = 0;
8555
8556 // try to parse integers first and fall back to floats
8557 if (number_type == token_type::value_unsigned)
8558 {
8559 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8560
8561 // we checked the number format before
8562 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8563
8564 if (errno == 0)
8565 {
8566 value_unsigned = static_cast<number_unsigned_t>(x);
8567 if (value_unsigned == x)
8568 {
8569 return token_type::value_unsigned;
8570 }
8571 }
8572 }
8573 else if (number_type == token_type::value_integer)
8574 {
8575 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8576
8577 // we checked the number format before
8578 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8579
8580 if (errno == 0)
8581 {
8582 value_integer = static_cast<number_integer_t>(x);
8583 if (value_integer == x)
8584 {
8585 return token_type::value_integer;
8586 }
8587 }
8588 }
8589
8590 // this code is reached if we parse a floating-point number or if an
8591 // integer conversion above failed
8592 strtof(value_float, token_buffer.data(), &endptr);
8593
8594 // we checked the number format before
8595 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8596
8597 return token_type::value_float;
8598 }
8599
8606 token_type scan_literal(const char_type* literal_text, const std::size_t length,
8607 token_type return_type)
8608 {
8609 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8610 for (std::size_t i = 1; i < length; ++i)
8611 {
8612 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8613 {
8614 error_message = "invalid literal";
8615 return token_type::parse_error;
8616 }
8617 }
8618 return return_type;
8619 }
8620
8622 // input management
8624
8626 void reset() noexcept
8627 {
8628 token_buffer.clear();
8629 token_string.clear();
8630 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8631 }
8632
8633 /*
8634 @brief get next character from the input
8635
8636 This function provides the interface to the used input adapter. It does
8637 not throw in case the input reached EOF, but returns a
8638 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8639 for use in error messages.
8640
8641 @return character read from the input
8642 */
8643 char_int_type get()
8644 {
8645 ++position.chars_read_total;
8646 ++position.chars_read_current_line;
8647
8648 if (next_unget)
8649 {
8650 // just reset the next_unget variable and work with current
8651 next_unget = false;
8652 }
8653 else
8654 {
8655 current = ia.get_character();
8656 }
8657
8658 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8659 {
8660 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8661 }
8662
8663 if (current == '\n')
8664 {
8665 ++position.lines_read;
8666 position.chars_read_current_line = 0;
8667 }
8668
8669 return current;
8670 }
8671
8680 void unget()
8681 {
8682 next_unget = true;
8683
8684 --position.chars_read_total;
8685
8686 // in case we "unget" a newline, we have to also decrement the lines_read
8687 if (position.chars_read_current_line == 0)
8688 {
8689 if (position.lines_read > 0)
8690 {
8691 --position.lines_read;
8692 }
8693 }
8694 else
8695 {
8696 --position.chars_read_current_line;
8697 }
8698
8699 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8700 {
8701 JSON_ASSERT(!token_string.empty());
8702 token_string.pop_back();
8703 }
8704 }
8705
8707 void add(char_int_type c)
8708 {
8709 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8710 }
8711
8712 public:
8714 // value getters
8716
8718 constexpr number_integer_t get_number_integer() const noexcept
8719 {
8720 return value_integer;
8721 }
8722
8724 constexpr number_unsigned_t get_number_unsigned() const noexcept
8725 {
8726 return value_unsigned;
8727 }
8728
8730 constexpr number_float_t get_number_float() const noexcept
8731 {
8732 return value_float;
8733 }
8734
8736 string_t& get_string()
8737 {
8738 return token_buffer;
8739 }
8740
8742 // diagnostics
8744
8746 constexpr position_t get_position() const noexcept
8747 {
8748 return position;
8749 }
8750
8754 std::string get_token_string() const
8755 {
8756 // escape control characters
8757 std::string result;
8758 for (const auto c : token_string)
8759 {
8760 if (static_cast<unsigned char>(c) <= '\x1F')
8761 {
8762 // escape control characters
8763 std::array<char, 9> cs{ {} };
8764 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8765 result += cs.data();
8766 }
8767 else
8768 {
8769 // add character as is
8770 result.push_back(static_cast<std::string::value_type>(c));
8771 }
8772 }
8773
8774 return result;
8775 }
8776
8779 constexpr const char* get_error_message() const noexcept
8780 {
8781 return error_message;
8782 }
8783
8785 // actual scanner
8787
8793 {
8794 if (get() == 0xEF)
8795 {
8796 // check if we completely parse the BOM
8797 return get() == 0xBB && get() == 0xBF;
8798 }
8799
8800 // the first character is not the beginning of the BOM; unget it to
8801 // process is later
8802 unget();
8803 return true;
8804 }
8805
8807 {
8808 do
8809 {
8810 get();
8811 } while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8812 }
8813
8815 {
8816 // initially, skip the BOM
8817 if (position.chars_read_total == 0 && !skip_bom())
8818 {
8819 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8820 return token_type::parse_error;
8821 }
8822
8823 // read next character and ignore whitespace
8824 skip_whitespace();
8825
8826 // ignore comments
8827 while (ignore_comments && current == '/')
8828 {
8829 if (!scan_comment())
8830 {
8831 return token_type::parse_error;
8832 }
8833
8834 // skip following whitespace
8835 skip_whitespace();
8836 }
8837
8838 switch (current)
8839 {
8840 // structural characters
8841 case '[':
8842 return token_type::begin_array;
8843 case ']':
8844 return token_type::end_array;
8845 case '{':
8846 return token_type::begin_object;
8847 case '}':
8848 return token_type::end_object;
8849 case ':':
8850 return token_type::name_separator;
8851 case ',':
8852 return token_type::value_separator;
8853
8854 // literals
8855 case 't':
8856 {
8857 std::array<char_type, 4> true_literal = { {static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')} };
8858 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8859 }
8860 case 'f':
8861 {
8862 std::array<char_type, 5> false_literal = { {static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')} };
8863 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8864 }
8865 case 'n':
8866 {
8867 std::array<char_type, 4> null_literal = { {static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')} };
8868 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8869 }
8870
8871 // string
8872 case '\"':
8873 return scan_string();
8874
8875 // number
8876 case '-':
8877 case '0':
8878 case '1':
8879 case '2':
8880 case '3':
8881 case '4':
8882 case '5':
8883 case '6':
8884 case '7':
8885 case '8':
8886 case '9':
8887 return scan_number();
8888
8889 // end of input (the null byte is needed when parsing from
8890 // string literals)
8891 case '\0':
8892 case std::char_traits<char_type>::eof():
8893 return token_type::end_of_input;
8894
8895 // error
8896 default:
8897 error_message = "invalid literal";
8898 return token_type::parse_error;
8899 }
8900 }
8901
8902 private:
8904 InputAdapterType ia;
8905
8907 const bool ignore_comments = false;
8908
8910 char_int_type current = std::char_traits<char_type>::eof();
8911
8913 bool next_unget = false;
8914
8916 position_t position{};
8917
8919 std::vector<char_type> token_string{};
8920
8922 string_t token_buffer{};
8923
8925 const char* error_message = "";
8926
8927 // number values
8928 number_integer_t value_integer = 0;
8929 number_unsigned_t value_unsigned = 0;
8930 number_float_t value_float = 0;
8931
8933 const char_int_type decimal_point_char = '.';
8934 };
8935
8936} // namespace detail
8938
8939// #include <nlohmann/detail/macro_scope.hpp>
8940
8941// #include <nlohmann/detail/meta/is_sax.hpp>
8942// __ _____ _____ _____
8943// __| | __| | | | JSON for Modern C++
8944// | | |__ | | | | | | version 3.11.2
8945// |_____|_____|_____|_|___| https://github.com/nlohmann/json
8946//
8947// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8948// SPDX-License-Identifier: MIT
8949
8950
8951
8952#include <cstdint> // size_t
8953#include <utility> // declval
8954#include <string> // string
8955
8956// #include <nlohmann/detail/abi_macros.hpp>
8957
8958// #include <nlohmann/detail/meta/detected.hpp>
8959
8960// #include <nlohmann/detail/meta/type_traits.hpp>
8961
8962
8964namespace detail
8965{
8966
8967 template<typename T>
8968 using null_function_t = decltype(std::declval<T&>().null());
8969
8970 template<typename T>
8972 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8973
8974 template<typename T, typename Integer>
8976 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8977
8978 template<typename T, typename Unsigned>
8980 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8981
8982 template<typename T, typename Float, typename String>
8983 using number_float_function_t = decltype(std::declval<T&>().number_float(
8984 std::declval<Float>(), std::declval<const String&>()));
8985
8986 template<typename T, typename String>
8988 decltype(std::declval<T&>().string(std::declval<String&>()));
8989
8990 template<typename T, typename Binary>
8992 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8993
8994 template<typename T>
8996 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8997
8998 template<typename T, typename String>
9000 decltype(std::declval<T&>().key(std::declval<String&>()));
9001
9002 template<typename T>
9003 using end_object_function_t = decltype(std::declval<T&>().end_object());
9004
9005 template<typename T>
9007 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9008
9009 template<typename T>
9010 using end_array_function_t = decltype(std::declval<T&>().end_array());
9011
9012 template<typename T, typename Exception>
9013 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9014 std::declval<std::size_t>(), std::declval<const std::string&>(),
9015 std::declval<const Exception&>()));
9016
9017 template<typename SAX, typename BasicJsonType>
9018 struct is_sax
9019 {
9020 private:
9022 "BasicJsonType must be of type basic_json<...>");
9023
9024 using number_integer_t = typename BasicJsonType::number_integer_t;
9025 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9026 using number_float_t = typename BasicJsonType::number_float_t;
9027 using string_t = typename BasicJsonType::string_t;
9028 using binary_t = typename BasicJsonType::binary_t;
9029 using exception_t = typename BasicJsonType::exception;
9030
9031 public:
9032 static constexpr bool value =
9046 };
9047
9048 template<typename SAX, typename BasicJsonType>
9050 {
9051 private:
9053 "BasicJsonType must be of type basic_json<...>");
9054
9055 using number_integer_t = typename BasicJsonType::number_integer_t;
9056 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9057 using number_float_t = typename BasicJsonType::number_float_t;
9058 using string_t = typename BasicJsonType::string_t;
9059 using binary_t = typename BasicJsonType::binary_t;
9060 using exception_t = typename BasicJsonType::exception;
9061
9062 public:
9064 "Missing/invalid function: bool null()");
9066 "Missing/invalid function: bool boolean(bool)");
9068 "Missing/invalid function: bool boolean(bool)");
9069 static_assert(
9071 number_integer_t>::value,
9072 "Missing/invalid function: bool number_integer(number_integer_t)");
9073 static_assert(
9075 number_unsigned_t>::value,
9076 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9077 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9078 number_float_t, string_t>::value,
9079 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9080 static_assert(
9082 "Missing/invalid function: bool string(string_t&)");
9083 static_assert(
9085 "Missing/invalid function: bool binary(binary_t&)");
9087 "Missing/invalid function: bool start_object(std::size_t)");
9089 "Missing/invalid function: bool key(string_t&)");
9091 "Missing/invalid function: bool end_object()");
9093 "Missing/invalid function: bool start_array(std::size_t)");
9095 "Missing/invalid function: bool end_array()");
9096 static_assert(
9098 "Missing/invalid function: bool parse_error(std::size_t, const "
9099 "std::string&, const exception&)");
9100 };
9101
9102} // namespace detail
9104
9105// #include <nlohmann/detail/meta/type_traits.hpp>
9106
9107// #include <nlohmann/detail/string_concat.hpp>
9108
9109// #include <nlohmann/detail/value_t.hpp>
9110
9111
9113namespace detail
9114{
9115
9118 {
9119 error,
9120 ignore,
9121 store
9122 };
9123
9131 static inline bool little_endianness(int num = 1) noexcept
9132 {
9133 return *reinterpret_cast<char*>(&num) == 1;
9134 }
9135
9136
9138 // binary reader //
9140
9144 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9146 {
9147 using number_integer_t = typename BasicJsonType::number_integer_t;
9148 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9149 using number_float_t = typename BasicJsonType::number_float_t;
9150 using string_t = typename BasicJsonType::string_t;
9151 using binary_t = typename BasicJsonType::binary_t;
9152 using json_sax_t = SAX;
9153 using char_type = typename InputAdapterType::char_type;
9154 using char_int_type = typename std::char_traits<char_type>::int_type;
9155
9156 public:
9162 explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9163 {
9165 }
9166
9167 // make class move-only
9169 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9171 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9172 ~binary_reader() = default;
9173
9183 bool sax_parse(const input_format_t format,
9184 json_sax_t* sax_,
9185 const bool strict = true,
9186 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9187 {
9188 sax = sax_;
9189 bool result = false;
9190
9191 switch (format)
9192 {
9194 result = parse_bson_internal();
9195 break;
9196
9198 result = parse_cbor_internal(true, tag_handler);
9199 break;
9200
9202 result = parse_msgpack_internal();
9203 break;
9204
9207 result = parse_ubjson_internal();
9208 break;
9209
9210 case input_format_t::json: // LCOV_EXCL_LINE
9211 default: // LCOV_EXCL_LINE
9212 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9213 }
9214
9215 // strict mode: next byte must be EOF
9216 if (result && strict)
9217 {
9218 if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9219 {
9220 get_ignore_noop();
9221 }
9222 else
9223 {
9224 get();
9225 }
9226
9227 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
9228 {
9229 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9230 exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9231 }
9232 }
9233
9234 return result;
9235 }
9236
9237 private:
9239 // BSON //
9241
9246 bool parse_bson_internal()
9247 {
9248 std::int32_t document_size{};
9249 get_number<std::int32_t, true>(input_format_t::bson, document_size);
9250
9251 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9252 {
9253 return false;
9254 }
9255
9256 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9257 {
9258 return false;
9259 }
9260
9261 return sax->end_object();
9262 }
9263
9271 bool get_bson_cstr(string_t& result)
9272 {
9273 auto out = std::back_inserter(result);
9274 while (true)
9275 {
9276 get();
9277 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9278 {
9279 return false;
9280 }
9281 if (current == 0x00)
9282 {
9283 return true;
9284 }
9285 *out++ = static_cast<typename string_t::value_type>(current);
9286 }
9287 }
9288
9300 template<typename NumberType>
9301 bool get_bson_string(const NumberType len, string_t& result)
9302 {
9303 if (JSON_HEDLEY_UNLIKELY(len < 1))
9304 {
9305 auto last_token = get_token_string();
9306 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9307 exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9308 }
9309
9310 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
9311 }
9312
9322 template<typename NumberType>
9323 bool get_bson_binary(const NumberType len, binary_t& result)
9324 {
9325 if (JSON_HEDLEY_UNLIKELY(len < 0))
9326 {
9327 auto last_token = get_token_string();
9328 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9329 exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9330 }
9331
9332 // All BSON binary values have a subtype
9333 std::uint8_t subtype{};
9334 get_number<std::uint8_t>(input_format_t::bson, subtype);
9335 result.set_subtype(subtype);
9336
9337 return get_binary(input_format_t::bson, len, result);
9338 }
9339
9350 bool parse_bson_element_internal(const char_int_type element_type,
9351 const std::size_t element_type_parse_position)
9352 {
9353 switch (element_type)
9354 {
9355 case 0x01: // double
9356 {
9357 double number{};
9358 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9359 }
9360
9361 case 0x02: // string
9362 {
9363 std::int32_t len{};
9364 string_t value;
9365 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
9366 }
9367
9368 case 0x03: // object
9369 {
9370 return parse_bson_internal();
9371 }
9372
9373 case 0x04: // array
9374 {
9375 return parse_bson_array();
9376 }
9377
9378 case 0x05: // binary
9379 {
9380 std::int32_t len{};
9381 binary_t value;
9382 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9383 }
9384
9385 case 0x08: // boolean
9386 {
9387 return sax->boolean(get() != 0);
9388 }
9389
9390 case 0x0A: // null
9391 {
9392 return sax->null();
9393 }
9394
9395 case 0x10: // int32
9396 {
9397 std::int32_t value{};
9398 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9399 }
9400
9401 case 0x12: // int64
9402 {
9403 std::int64_t value{};
9404 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9405 }
9406
9407 default: // anything else not supported (yet)
9408 {
9409 std::array<char, 3> cr{ {} };
9410 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9411 const std::string cr_str{ cr.data() };
9412 return sax->parse_error(element_type_parse_position, cr_str,
9413 parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9414 }
9415 }
9416 }
9417
9430 bool parse_bson_element_list(const bool is_array)
9431 {
9432 string_t key;
9433
9434 while (auto element_type = get())
9435 {
9436 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9437 {
9438 return false;
9439 }
9440
9441 const std::size_t element_type_parse_position = chars_read;
9442 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9443 {
9444 return false;
9445 }
9446
9447 if (!is_array && !sax->key(key))
9448 {
9449 return false;
9450 }
9451
9452 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9453 {
9454 return false;
9455 }
9456
9457 // get_bson_cstr only appends
9458 key.clear();
9459 }
9460
9461 return true;
9462 }
9463
9468 bool parse_bson_array()
9469 {
9470 std::int32_t document_size{};
9471 get_number<std::int32_t, true>(input_format_t::bson, document_size);
9472
9473 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9474 {
9475 return false;
9476 }
9477
9478 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9479 {
9480 return false;
9481 }
9482
9483 return sax->end_array();
9484 }
9485
9487 // CBOR //
9489
9498 bool parse_cbor_internal(const bool get_char,
9499 const cbor_tag_handler_t tag_handler)
9500 {
9501 switch (get_char ? get() : current)
9502 {
9503 // EOF
9504 case std::char_traits<char_type>::eof():
9505 return unexpect_eof(input_format_t::cbor, "value");
9506
9507 // Integer 0x00..0x17 (0..23)
9508 case 0x00:
9509 case 0x01:
9510 case 0x02:
9511 case 0x03:
9512 case 0x04:
9513 case 0x05:
9514 case 0x06:
9515 case 0x07:
9516 case 0x08:
9517 case 0x09:
9518 case 0x0A:
9519 case 0x0B:
9520 case 0x0C:
9521 case 0x0D:
9522 case 0x0E:
9523 case 0x0F:
9524 case 0x10:
9525 case 0x11:
9526 case 0x12:
9527 case 0x13:
9528 case 0x14:
9529 case 0x15:
9530 case 0x16:
9531 case 0x17:
9532 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9533
9534 case 0x18: // Unsigned integer (one-byte uint8_t follows)
9535 {
9536 std::uint8_t number{};
9537 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9538 }
9539
9540 case 0x19: // Unsigned integer (two-byte uint16_t follows)
9541 {
9542 std::uint16_t number{};
9543 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9544 }
9545
9546 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9547 {
9548 std::uint32_t number{};
9549 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9550 }
9551
9552 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9553 {
9554 std::uint64_t number{};
9555 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9556 }
9557
9558 // Negative integer -1-0x00..-1-0x17 (-1..-24)
9559 case 0x20:
9560 case 0x21:
9561 case 0x22:
9562 case 0x23:
9563 case 0x24:
9564 case 0x25:
9565 case 0x26:
9566 case 0x27:
9567 case 0x28:
9568 case 0x29:
9569 case 0x2A:
9570 case 0x2B:
9571 case 0x2C:
9572 case 0x2D:
9573 case 0x2E:
9574 case 0x2F:
9575 case 0x30:
9576 case 0x31:
9577 case 0x32:
9578 case 0x33:
9579 case 0x34:
9580 case 0x35:
9581 case 0x36:
9582 case 0x37:
9583 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9584
9585 case 0x38: // Negative integer (one-byte uint8_t follows)
9586 {
9587 std::uint8_t number{};
9588 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9589 }
9590
9591 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9592 {
9593 std::uint16_t number{};
9594 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9595 }
9596
9597 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9598 {
9599 std::uint32_t number{};
9600 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9601 }
9602
9603 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9604 {
9605 std::uint64_t number{};
9606 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9607 - static_cast<number_integer_t>(number));
9608 }
9609
9610 // Binary data (0x00..0x17 bytes follow)
9611 case 0x40:
9612 case 0x41:
9613 case 0x42:
9614 case 0x43:
9615 case 0x44:
9616 case 0x45:
9617 case 0x46:
9618 case 0x47:
9619 case 0x48:
9620 case 0x49:
9621 case 0x4A:
9622 case 0x4B:
9623 case 0x4C:
9624 case 0x4D:
9625 case 0x4E:
9626 case 0x4F:
9627 case 0x50:
9628 case 0x51:
9629 case 0x52:
9630 case 0x53:
9631 case 0x54:
9632 case 0x55:
9633 case 0x56:
9634 case 0x57:
9635 case 0x58: // Binary data (one-byte uint8_t for n follows)
9636 case 0x59: // Binary data (two-byte uint16_t for n follow)
9637 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9638 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9639 case 0x5F: // Binary data (indefinite length)
9640 {
9641 binary_t b;
9642 return get_cbor_binary(b) && sax->binary(b);
9643 }
9644
9645 // UTF-8 string (0x00..0x17 bytes follow)
9646 case 0x60:
9647 case 0x61:
9648 case 0x62:
9649 case 0x63:
9650 case 0x64:
9651 case 0x65:
9652 case 0x66:
9653 case 0x67:
9654 case 0x68:
9655 case 0x69:
9656 case 0x6A:
9657 case 0x6B:
9658 case 0x6C:
9659 case 0x6D:
9660 case 0x6E:
9661 case 0x6F:
9662 case 0x70:
9663 case 0x71:
9664 case 0x72:
9665 case 0x73:
9666 case 0x74:
9667 case 0x75:
9668 case 0x76:
9669 case 0x77:
9670 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9671 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9672 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9673 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9674 case 0x7F: // UTF-8 string (indefinite length)
9675 {
9676 string_t s;
9677 return get_cbor_string(s) && sax->string(s);
9678 }
9679
9680 // array (0x00..0x17 data items follow)
9681 case 0x80:
9682 case 0x81:
9683 case 0x82:
9684 case 0x83:
9685 case 0x84:
9686 case 0x85:
9687 case 0x86:
9688 case 0x87:
9689 case 0x88:
9690 case 0x89:
9691 case 0x8A:
9692 case 0x8B:
9693 case 0x8C:
9694 case 0x8D:
9695 case 0x8E:
9696 case 0x8F:
9697 case 0x90:
9698 case 0x91:
9699 case 0x92:
9700 case 0x93:
9701 case 0x94:
9702 case 0x95:
9703 case 0x96:
9704 case 0x97:
9705 return get_cbor_array(
9706 conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9707
9708 case 0x98: // array (one-byte uint8_t for n follows)
9709 {
9710 std::uint8_t len{};
9711 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9712 }
9713
9714 case 0x99: // array (two-byte uint16_t for n follow)
9715 {
9716 std::uint16_t len{};
9717 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9718 }
9719
9720 case 0x9A: // array (four-byte uint32_t for n follow)
9721 {
9722 std::uint32_t len{};
9723 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9724 }
9725
9726 case 0x9B: // array (eight-byte uint64_t for n follow)
9727 {
9728 std::uint64_t len{};
9729 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9730 }
9731
9732 case 0x9F: // array (indefinite length)
9733 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9734
9735 // map (0x00..0x17 pairs of data items follow)
9736 case 0xA0:
9737 case 0xA1:
9738 case 0xA2:
9739 case 0xA3:
9740 case 0xA4:
9741 case 0xA5:
9742 case 0xA6:
9743 case 0xA7:
9744 case 0xA8:
9745 case 0xA9:
9746 case 0xAA:
9747 case 0xAB:
9748 case 0xAC:
9749 case 0xAD:
9750 case 0xAE:
9751 case 0xAF:
9752 case 0xB0:
9753 case 0xB1:
9754 case 0xB2:
9755 case 0xB3:
9756 case 0xB4:
9757 case 0xB5:
9758 case 0xB6:
9759 case 0xB7:
9760 return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9761
9762 case 0xB8: // map (one-byte uint8_t for n follows)
9763 {
9764 std::uint8_t len{};
9765 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9766 }
9767
9768 case 0xB9: // map (two-byte uint16_t for n follow)
9769 {
9770 std::uint16_t len{};
9771 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9772 }
9773
9774 case 0xBA: // map (four-byte uint32_t for n follow)
9775 {
9776 std::uint32_t len{};
9777 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9778 }
9779
9780 case 0xBB: // map (eight-byte uint64_t for n follow)
9781 {
9782 std::uint64_t len{};
9783 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9784 }
9785
9786 case 0xBF: // map (indefinite length)
9787 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9788
9789 case 0xC6: // tagged item
9790 case 0xC7:
9791 case 0xC8:
9792 case 0xC9:
9793 case 0xCA:
9794 case 0xCB:
9795 case 0xCC:
9796 case 0xCD:
9797 case 0xCE:
9798 case 0xCF:
9799 case 0xD0:
9800 case 0xD1:
9801 case 0xD2:
9802 case 0xD3:
9803 case 0xD4:
9804 case 0xD8: // tagged item (1 bytes follow)
9805 case 0xD9: // tagged item (2 bytes follow)
9806 case 0xDA: // tagged item (4 bytes follow)
9807 case 0xDB: // tagged item (8 bytes follow)
9808 {
9809 switch (tag_handler)
9810 {
9812 {
9813 auto last_token = get_token_string();
9814 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9815 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9816 }
9817
9819 {
9820 // ignore binary subtype
9821 switch (current)
9822 {
9823 case 0xD8:
9824 {
9825 std::uint8_t subtype_to_ignore{};
9826 get_number(input_format_t::cbor, subtype_to_ignore);
9827 break;
9828 }
9829 case 0xD9:
9830 {
9831 std::uint16_t subtype_to_ignore{};
9832 get_number(input_format_t::cbor, subtype_to_ignore);
9833 break;
9834 }
9835 case 0xDA:
9836 {
9837 std::uint32_t subtype_to_ignore{};
9838 get_number(input_format_t::cbor, subtype_to_ignore);
9839 break;
9840 }
9841 case 0xDB:
9842 {
9843 std::uint64_t subtype_to_ignore{};
9844 get_number(input_format_t::cbor, subtype_to_ignore);
9845 break;
9846 }
9847 default:
9848 break;
9849 }
9850 return parse_cbor_internal(true, tag_handler);
9851 }
9852
9854 {
9855 binary_t b;
9856 // use binary subtype and store in binary container
9857 switch (current)
9858 {
9859 case 0xD8:
9860 {
9861 std::uint8_t subtype{};
9862 get_number(input_format_t::cbor, subtype);
9863 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9864 break;
9865 }
9866 case 0xD9:
9867 {
9868 std::uint16_t subtype{};
9869 get_number(input_format_t::cbor, subtype);
9870 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9871 break;
9872 }
9873 case 0xDA:
9874 {
9875 std::uint32_t subtype{};
9876 get_number(input_format_t::cbor, subtype);
9877 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9878 break;
9879 }
9880 case 0xDB:
9881 {
9882 std::uint64_t subtype{};
9883 get_number(input_format_t::cbor, subtype);
9884 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9885 break;
9886 }
9887 default:
9888 return parse_cbor_internal(true, tag_handler);
9889 }
9890 get();
9891 return get_cbor_binary(b) && sax->binary(b);
9892 }
9893
9894 default: // LCOV_EXCL_LINE
9895 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9896 return false; // LCOV_EXCL_LINE
9897 }
9898 }
9899
9900 case 0xF4: // false
9901 return sax->boolean(false);
9902
9903 case 0xF5: // true
9904 return sax->boolean(true);
9905
9906 case 0xF6: // null
9907 return sax->null();
9908
9909 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9910 {
9911 const auto byte1_raw = get();
9912 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9913 {
9914 return false;
9915 }
9916 const auto byte2_raw = get();
9917 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9918 {
9919 return false;
9920 }
9921
9922 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9923 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9924
9925 // code from RFC 7049, Appendix D, Figure 3:
9926 // As half-precision floating-point numbers were only added
9927 // to IEEE 754 in 2008, today's programming platforms often
9928 // still only have limited support for them. It is very
9929 // easy to include at least decoding support for them even
9930 // without such support. An example of a small decoder for
9931 // half-precision floating-point numbers in the C language
9932 // is shown in Fig. 3.
9933 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9934 const double val = [&half]
9935 {
9936 const int exp = (half >> 10u) & 0x1Fu;
9937 const unsigned int mant = half & 0x3FFu;
9938 JSON_ASSERT(0 <= exp && exp <= 32);
9939 JSON_ASSERT(mant <= 1024);
9940 switch (exp)
9941 {
9942 case 0:
9943 return std::ldexp(mant, -24);
9944 case 31:
9945 return (mant == 0)
9946 ? std::numeric_limits<double>::infinity()
9947 : std::numeric_limits<double>::quiet_NaN();
9948 default:
9949 return std::ldexp(mant + 1024, exp - 25);
9950 }
9951 }();
9952 return sax->number_float((half & 0x8000u) != 0
9953 ? static_cast<number_float_t>(-val)
9954 : static_cast<number_float_t>(val), "");
9955 }
9956
9957 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9958 {
9959 float number{};
9960 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9961 }
9962
9963 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9964 {
9965 double number{};
9966 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9967 }
9968
9969 default: // anything else (0xFF is handled inside the other types)
9970 {
9971 auto last_token = get_token_string();
9972 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9973 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9974 }
9975 }
9976 }
9977
9989 bool get_cbor_string(string_t& result)
9990 {
9991 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9992 {
9993 return false;
9994 }
9995
9996 switch (current)
9997 {
9998 // UTF-8 string (0x00..0x17 bytes follow)
9999 case 0x60:
10000 case 0x61:
10001 case 0x62:
10002 case 0x63:
10003 case 0x64:
10004 case 0x65:
10005 case 0x66:
10006 case 0x67:
10007 case 0x68:
10008 case 0x69:
10009 case 0x6A:
10010 case 0x6B:
10011 case 0x6C:
10012 case 0x6D:
10013 case 0x6E:
10014 case 0x6F:
10015 case 0x70:
10016 case 0x71:
10017 case 0x72:
10018 case 0x73:
10019 case 0x74:
10020 case 0x75:
10021 case 0x76:
10022 case 0x77:
10023 {
10024 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10025 }
10026
10027 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10028 {
10029 std::uint8_t len{};
10030 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10031 }
10032
10033 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10034 {
10035 std::uint16_t len{};
10036 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10037 }
10038
10039 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10040 {
10041 std::uint32_t len{};
10042 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10043 }
10044
10045 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10046 {
10047 std::uint64_t len{};
10048 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10049 }
10050
10051 case 0x7F: // UTF-8 string (indefinite length)
10052 {
10053 while (get() != 0xFF)
10054 {
10055 string_t chunk;
10056 if (!get_cbor_string(chunk))
10057 {
10058 return false;
10059 }
10060 result.append(chunk);
10061 }
10062 return true;
10063 }
10064
10065 default:
10066 {
10067 auto last_token = get_token_string();
10068 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10069 exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10070 }
10071 }
10072 }
10073
10085 bool get_cbor_binary(binary_t& result)
10086 {
10087 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10088 {
10089 return false;
10090 }
10091
10092 switch (current)
10093 {
10094 // Binary data (0x00..0x17 bytes follow)
10095 case 0x40:
10096 case 0x41:
10097 case 0x42:
10098 case 0x43:
10099 case 0x44:
10100 case 0x45:
10101 case 0x46:
10102 case 0x47:
10103 case 0x48:
10104 case 0x49:
10105 case 0x4A:
10106 case 0x4B:
10107 case 0x4C:
10108 case 0x4D:
10109 case 0x4E:
10110 case 0x4F:
10111 case 0x50:
10112 case 0x51:
10113 case 0x52:
10114 case 0x53:
10115 case 0x54:
10116 case 0x55:
10117 case 0x56:
10118 case 0x57:
10119 {
10120 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10121 }
10122
10123 case 0x58: // Binary data (one-byte uint8_t for n follows)
10124 {
10125 std::uint8_t len{};
10126 return get_number(input_format_t::cbor, len) &&
10127 get_binary(input_format_t::cbor, len, result);
10128 }
10129
10130 case 0x59: // Binary data (two-byte uint16_t for n follow)
10131 {
10132 std::uint16_t len{};
10133 return get_number(input_format_t::cbor, len) &&
10134 get_binary(input_format_t::cbor, len, result);
10135 }
10136
10137 case 0x5A: // Binary data (four-byte uint32_t for n follow)
10138 {
10139 std::uint32_t len{};
10140 return get_number(input_format_t::cbor, len) &&
10141 get_binary(input_format_t::cbor, len, result);
10142 }
10143
10144 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10145 {
10146 std::uint64_t len{};
10147 return get_number(input_format_t::cbor, len) &&
10148 get_binary(input_format_t::cbor, len, result);
10149 }
10150
10151 case 0x5F: // Binary data (indefinite length)
10152 {
10153 while (get() != 0xFF)
10154 {
10155 binary_t chunk;
10156 if (!get_cbor_binary(chunk))
10157 {
10158 return false;
10159 }
10160 result.insert(result.end(), chunk.begin(), chunk.end());
10161 }
10162 return true;
10163 }
10164
10165 default:
10166 {
10167 auto last_token = get_token_string();
10168 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10169 exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
10170 }
10171 }
10172 }
10173
10180 bool get_cbor_array(const std::size_t len,
10181 const cbor_tag_handler_t tag_handler)
10182 {
10183 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10184 {
10185 return false;
10186 }
10187
10188 if (len != static_cast<std::size_t>(-1))
10189 {
10190 for (std::size_t i = 0; i < len; ++i)
10191 {
10192 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10193 {
10194 return false;
10195 }
10196 }
10197 }
10198 else
10199 {
10200 while (get() != 0xFF)
10201 {
10202 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10203 {
10204 return false;
10205 }
10206 }
10207 }
10208
10209 return sax->end_array();
10210 }
10211
10218 bool get_cbor_object(const std::size_t len,
10219 const cbor_tag_handler_t tag_handler)
10220 {
10221 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10222 {
10223 return false;
10224 }
10225
10226 if (len != 0)
10227 {
10228 string_t key;
10229 if (len != static_cast<std::size_t>(-1))
10230 {
10231 for (std::size_t i = 0; i < len; ++i)
10232 {
10233 get();
10234 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10235 {
10236 return false;
10237 }
10238
10239 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10240 {
10241 return false;
10242 }
10243 key.clear();
10244 }
10245 }
10246 else
10247 {
10248 while (get() != 0xFF)
10249 {
10250 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10251 {
10252 return false;
10253 }
10254
10255 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10256 {
10257 return false;
10258 }
10259 key.clear();
10260 }
10261 }
10262 }
10263
10264 return sax->end_object();
10265 }
10266
10268 // MsgPack //
10270
10274 bool parse_msgpack_internal()
10275 {
10276 switch (get())
10277 {
10278 // EOF
10279 case std::char_traits<char_type>::eof():
10280 return unexpect_eof(input_format_t::msgpack, "value");
10281
10282 // positive fixint
10283 case 0x00:
10284 case 0x01:
10285 case 0x02:
10286 case 0x03:
10287 case 0x04:
10288 case 0x05:
10289 case 0x06:
10290 case 0x07:
10291 case 0x08:
10292 case 0x09:
10293 case 0x0A:
10294 case 0x0B:
10295 case 0x0C:
10296 case 0x0D:
10297 case 0x0E:
10298 case 0x0F:
10299 case 0x10:
10300 case 0x11:
10301 case 0x12:
10302 case 0x13:
10303 case 0x14:
10304 case 0x15:
10305 case 0x16:
10306 case 0x17:
10307 case 0x18:
10308 case 0x19:
10309 case 0x1A:
10310 case 0x1B:
10311 case 0x1C:
10312 case 0x1D:
10313 case 0x1E:
10314 case 0x1F:
10315 case 0x20:
10316 case 0x21:
10317 case 0x22:
10318 case 0x23:
10319 case 0x24:
10320 case 0x25:
10321 case 0x26:
10322 case 0x27:
10323 case 0x28:
10324 case 0x29:
10325 case 0x2A:
10326 case 0x2B:
10327 case 0x2C:
10328 case 0x2D:
10329 case 0x2E:
10330 case 0x2F:
10331 case 0x30:
10332 case 0x31:
10333 case 0x32:
10334 case 0x33:
10335 case 0x34:
10336 case 0x35:
10337 case 0x36:
10338 case 0x37:
10339 case 0x38:
10340 case 0x39:
10341 case 0x3A:
10342 case 0x3B:
10343 case 0x3C:
10344 case 0x3D:
10345 case 0x3E:
10346 case 0x3F:
10347 case 0x40:
10348 case 0x41:
10349 case 0x42:
10350 case 0x43:
10351 case 0x44:
10352 case 0x45:
10353 case 0x46:
10354 case 0x47:
10355 case 0x48:
10356 case 0x49:
10357 case 0x4A:
10358 case 0x4B:
10359 case 0x4C:
10360 case 0x4D:
10361 case 0x4E:
10362 case 0x4F:
10363 case 0x50:
10364 case 0x51:
10365 case 0x52:
10366 case 0x53:
10367 case 0x54:
10368 case 0x55:
10369 case 0x56:
10370 case 0x57:
10371 case 0x58:
10372 case 0x59:
10373 case 0x5A:
10374 case 0x5B:
10375 case 0x5C:
10376 case 0x5D:
10377 case 0x5E:
10378 case 0x5F:
10379 case 0x60:
10380 case 0x61:
10381 case 0x62:
10382 case 0x63:
10383 case 0x64:
10384 case 0x65:
10385 case 0x66:
10386 case 0x67:
10387 case 0x68:
10388 case 0x69:
10389 case 0x6A:
10390 case 0x6B:
10391 case 0x6C:
10392 case 0x6D:
10393 case 0x6E:
10394 case 0x6F:
10395 case 0x70:
10396 case 0x71:
10397 case 0x72:
10398 case 0x73:
10399 case 0x74:
10400 case 0x75:
10401 case 0x76:
10402 case 0x77:
10403 case 0x78:
10404 case 0x79:
10405 case 0x7A:
10406 case 0x7B:
10407 case 0x7C:
10408 case 0x7D:
10409 case 0x7E:
10410 case 0x7F:
10411 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10412
10413 // fixmap
10414 case 0x80:
10415 case 0x81:
10416 case 0x82:
10417 case 0x83:
10418 case 0x84:
10419 case 0x85:
10420 case 0x86:
10421 case 0x87:
10422 case 0x88:
10423 case 0x89:
10424 case 0x8A:
10425 case 0x8B:
10426 case 0x8C:
10427 case 0x8D:
10428 case 0x8E:
10429 case 0x8F:
10430 return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10431
10432 // fixarray
10433 case 0x90:
10434 case 0x91:
10435 case 0x92:
10436 case 0x93:
10437 case 0x94:
10438 case 0x95:
10439 case 0x96:
10440 case 0x97:
10441 case 0x98:
10442 case 0x99:
10443 case 0x9A:
10444 case 0x9B:
10445 case 0x9C:
10446 case 0x9D:
10447 case 0x9E:
10448 case 0x9F:
10449 return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10450
10451 // fixstr
10452 case 0xA0:
10453 case 0xA1:
10454 case 0xA2:
10455 case 0xA3:
10456 case 0xA4:
10457 case 0xA5:
10458 case 0xA6:
10459 case 0xA7:
10460 case 0xA8:
10461 case 0xA9:
10462 case 0xAA:
10463 case 0xAB:
10464 case 0xAC:
10465 case 0xAD:
10466 case 0xAE:
10467 case 0xAF:
10468 case 0xB0:
10469 case 0xB1:
10470 case 0xB2:
10471 case 0xB3:
10472 case 0xB4:
10473 case 0xB5:
10474 case 0xB6:
10475 case 0xB7:
10476 case 0xB8:
10477 case 0xB9:
10478 case 0xBA:
10479 case 0xBB:
10480 case 0xBC:
10481 case 0xBD:
10482 case 0xBE:
10483 case 0xBF:
10484 case 0xD9: // str 8
10485 case 0xDA: // str 16
10486 case 0xDB: // str 32
10487 {
10488 string_t s;
10489 return get_msgpack_string(s) && sax->string(s);
10490 }
10491
10492 case 0xC0: // nil
10493 return sax->null();
10494
10495 case 0xC2: // false
10496 return sax->boolean(false);
10497
10498 case 0xC3: // true
10499 return sax->boolean(true);
10500
10501 case 0xC4: // bin 8
10502 case 0xC5: // bin 16
10503 case 0xC6: // bin 32
10504 case 0xC7: // ext 8
10505 case 0xC8: // ext 16
10506 case 0xC9: // ext 32
10507 case 0xD4: // fixext 1
10508 case 0xD5: // fixext 2
10509 case 0xD6: // fixext 4
10510 case 0xD7: // fixext 8
10511 case 0xD8: // fixext 16
10512 {
10513 binary_t b;
10514 return get_msgpack_binary(b) && sax->binary(b);
10515 }
10516
10517 case 0xCA: // float 32
10518 {
10519 float number{};
10520 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10521 }
10522
10523 case 0xCB: // float 64
10524 {
10525 double number{};
10526 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10527 }
10528
10529 case 0xCC: // uint 8
10530 {
10531 std::uint8_t number{};
10532 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10533 }
10534
10535 case 0xCD: // uint 16
10536 {
10537 std::uint16_t number{};
10538 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10539 }
10540
10541 case 0xCE: // uint 32
10542 {
10543 std::uint32_t number{};
10544 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10545 }
10546
10547 case 0xCF: // uint 64
10548 {
10549 std::uint64_t number{};
10550 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10551 }
10552
10553 case 0xD0: // int 8
10554 {
10555 std::int8_t number{};
10556 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10557 }
10558
10559 case 0xD1: // int 16
10560 {
10561 std::int16_t number{};
10562 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10563 }
10564
10565 case 0xD2: // int 32
10566 {
10567 std::int32_t number{};
10568 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10569 }
10570
10571 case 0xD3: // int 64
10572 {
10573 std::int64_t number{};
10574 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10575 }
10576
10577 case 0xDC: // array 16
10578 {
10579 std::uint16_t len{};
10580 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10581 }
10582
10583 case 0xDD: // array 32
10584 {
10585 std::uint32_t len{};
10586 return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10587 }
10588
10589 case 0xDE: // map 16
10590 {
10591 std::uint16_t len{};
10592 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10593 }
10594
10595 case 0xDF: // map 32
10596 {
10597 std::uint32_t len{};
10598 return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10599 }
10600
10601 // negative fixint
10602 case 0xE0:
10603 case 0xE1:
10604 case 0xE2:
10605 case 0xE3:
10606 case 0xE4:
10607 case 0xE5:
10608 case 0xE6:
10609 case 0xE7:
10610 case 0xE8:
10611 case 0xE9:
10612 case 0xEA:
10613 case 0xEB:
10614 case 0xEC:
10615 case 0xED:
10616 case 0xEE:
10617 case 0xEF:
10618 case 0xF0:
10619 case 0xF1:
10620 case 0xF2:
10621 case 0xF3:
10622 case 0xF4:
10623 case 0xF5:
10624 case 0xF6:
10625 case 0xF7:
10626 case 0xF8:
10627 case 0xF9:
10628 case 0xFA:
10629 case 0xFB:
10630 case 0xFC:
10631 case 0xFD:
10632 case 0xFE:
10633 case 0xFF:
10634 return sax->number_integer(static_cast<std::int8_t>(current));
10635
10636 default: // anything else
10637 {
10638 auto last_token = get_token_string();
10639 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10640 exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10641 }
10642 }
10643 }
10644
10655 bool get_msgpack_string(string_t& result)
10656 {
10657 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10658 {
10659 return false;
10660 }
10661
10662 switch (current)
10663 {
10664 // fixstr
10665 case 0xA0:
10666 case 0xA1:
10667 case 0xA2:
10668 case 0xA3:
10669 case 0xA4:
10670 case 0xA5:
10671 case 0xA6:
10672 case 0xA7:
10673 case 0xA8:
10674 case 0xA9:
10675 case 0xAA:
10676 case 0xAB:
10677 case 0xAC:
10678 case 0xAD:
10679 case 0xAE:
10680 case 0xAF:
10681 case 0xB0:
10682 case 0xB1:
10683 case 0xB2:
10684 case 0xB3:
10685 case 0xB4:
10686 case 0xB5:
10687 case 0xB6:
10688 case 0xB7:
10689 case 0xB8:
10690 case 0xB9:
10691 case 0xBA:
10692 case 0xBB:
10693 case 0xBC:
10694 case 0xBD:
10695 case 0xBE:
10696 case 0xBF:
10697 {
10698 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10699 }
10700
10701 case 0xD9: // str 8
10702 {
10703 std::uint8_t len{};
10704 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10705 }
10706
10707 case 0xDA: // str 16
10708 {
10709 std::uint16_t len{};
10710 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10711 }
10712
10713 case 0xDB: // str 32
10714 {
10715 std::uint32_t len{};
10716 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10717 }
10718
10719 default:
10720 {
10721 auto last_token = get_token_string();
10722 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10723 exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10724 }
10725 }
10726 }
10727
10738 bool get_msgpack_binary(binary_t& result)
10739 {
10740 // helper function to set the subtype
10741 auto assign_and_return_true = [&result](std::int8_t subtype)
10742 {
10743 result.set_subtype(static_cast<std::uint8_t>(subtype));
10744 return true;
10745 };
10746
10747 switch (current)
10748 {
10749 case 0xC4: // bin 8
10750 {
10751 std::uint8_t len{};
10752 return get_number(input_format_t::msgpack, len) &&
10753 get_binary(input_format_t::msgpack, len, result);
10754 }
10755
10756 case 0xC5: // bin 16
10757 {
10758 std::uint16_t len{};
10759 return get_number(input_format_t::msgpack, len) &&
10760 get_binary(input_format_t::msgpack, len, result);
10761 }
10762
10763 case 0xC6: // bin 32
10764 {
10765 std::uint32_t len{};
10766 return get_number(input_format_t::msgpack, len) &&
10767 get_binary(input_format_t::msgpack, len, result);
10768 }
10769
10770 case 0xC7: // ext 8
10771 {
10772 std::uint8_t len{};
10773 std::int8_t subtype{};
10774 return get_number(input_format_t::msgpack, len) &&
10775 get_number(input_format_t::msgpack, subtype) &&
10776 get_binary(input_format_t::msgpack, len, result) &&
10777 assign_and_return_true(subtype);
10778 }
10779
10780 case 0xC8: // ext 16
10781 {
10782 std::uint16_t len{};
10783 std::int8_t subtype{};
10784 return get_number(input_format_t::msgpack, len) &&
10785 get_number(input_format_t::msgpack, subtype) &&
10786 get_binary(input_format_t::msgpack, len, result) &&
10787 assign_and_return_true(subtype);
10788 }
10789
10790 case 0xC9: // ext 32
10791 {
10792 std::uint32_t len{};
10793 std::int8_t subtype{};
10794 return get_number(input_format_t::msgpack, len) &&
10795 get_number(input_format_t::msgpack, subtype) &&
10796 get_binary(input_format_t::msgpack, len, result) &&
10797 assign_and_return_true(subtype);
10798 }
10799
10800 case 0xD4: // fixext 1
10801 {
10802 std::int8_t subtype{};
10803 return get_number(input_format_t::msgpack, subtype) &&
10804 get_binary(input_format_t::msgpack, 1, result) &&
10805 assign_and_return_true(subtype);
10806 }
10807
10808 case 0xD5: // fixext 2
10809 {
10810 std::int8_t subtype{};
10811 return get_number(input_format_t::msgpack, subtype) &&
10812 get_binary(input_format_t::msgpack, 2, result) &&
10813 assign_and_return_true(subtype);
10814 }
10815
10816 case 0xD6: // fixext 4
10817 {
10818 std::int8_t subtype{};
10819 return get_number(input_format_t::msgpack, subtype) &&
10820 get_binary(input_format_t::msgpack, 4, result) &&
10821 assign_and_return_true(subtype);
10822 }
10823
10824 case 0xD7: // fixext 8
10825 {
10826 std::int8_t subtype{};
10827 return get_number(input_format_t::msgpack, subtype) &&
10828 get_binary(input_format_t::msgpack, 8, result) &&
10829 assign_and_return_true(subtype);
10830 }
10831
10832 case 0xD8: // fixext 16
10833 {
10834 std::int8_t subtype{};
10835 return get_number(input_format_t::msgpack, subtype) &&
10836 get_binary(input_format_t::msgpack, 16, result) &&
10837 assign_and_return_true(subtype);
10838 }
10839
10840 default: // LCOV_EXCL_LINE
10841 return false; // LCOV_EXCL_LINE
10842 }
10843 }
10844
10849 bool get_msgpack_array(const std::size_t len)
10850 {
10851 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10852 {
10853 return false;
10854 }
10855
10856 for (std::size_t i = 0; i < len; ++i)
10857 {
10858 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10859 {
10860 return false;
10861 }
10862 }
10863
10864 return sax->end_array();
10865 }
10866
10871 bool get_msgpack_object(const std::size_t len)
10872 {
10873 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10874 {
10875 return false;
10876 }
10877
10878 string_t key;
10879 for (std::size_t i = 0; i < len; ++i)
10880 {
10881 get();
10882 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10883 {
10884 return false;
10885 }
10886
10887 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10888 {
10889 return false;
10890 }
10891 key.clear();
10892 }
10893
10894 return sax->end_object();
10895 }
10896
10898 // UBJSON //
10900
10908 bool parse_ubjson_internal(const bool get_char = true)
10909 {
10910 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10911 }
10912
10927 bool get_ubjson_string(string_t& result, const bool get_char = true)
10928 {
10929 if (get_char)
10930 {
10931 get(); // TODO(niels): may we ignore N here?
10932 }
10933
10934 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10935 {
10936 return false;
10937 }
10938
10939 switch (current)
10940 {
10941 case 'U':
10942 {
10943 std::uint8_t len{};
10944 return get_number(input_format, len) && get_string(input_format, len, result);
10945 }
10946
10947 case 'i':
10948 {
10949 std::int8_t len{};
10950 return get_number(input_format, len) && get_string(input_format, len, result);
10951 }
10952
10953 case 'I':
10954 {
10955 std::int16_t len{};
10956 return get_number(input_format, len) && get_string(input_format, len, result);
10957 }
10958
10959 case 'l':
10960 {
10961 std::int32_t len{};
10962 return get_number(input_format, len) && get_string(input_format, len, result);
10963 }
10964
10965 case 'L':
10966 {
10967 std::int64_t len{};
10968 return get_number(input_format, len) && get_string(input_format, len, result);
10969 }
10970
10971 case 'u':
10972 {
10973 if (input_format != input_format_t::bjdata)
10974 {
10975 break;
10976 }
10977 std::uint16_t len{};
10978 return get_number(input_format, len) && get_string(input_format, len, result);
10979 }
10980
10981 case 'm':
10982 {
10983 if (input_format != input_format_t::bjdata)
10984 {
10985 break;
10986 }
10987 std::uint32_t len{};
10988 return get_number(input_format, len) && get_string(input_format, len, result);
10989 }
10990
10991 case 'M':
10992 {
10993 if (input_format != input_format_t::bjdata)
10994 {
10995 break;
10996 }
10997 std::uint64_t len{};
10998 return get_number(input_format, len) && get_string(input_format, len, result);
10999 }
11000
11001 default:
11002 break;
11003 }
11004 auto last_token = get_token_string();
11005 std::string message;
11006
11007 if (input_format != input_format_t::bjdata)
11008 {
11009 message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11010 }
11011 else
11012 {
11013 message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11014 }
11015 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11016 }
11017
11022 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11023 {
11024 std::pair<std::size_t, char_int_type> size_and_type;
11025 size_t dimlen = 0;
11026 bool no_ndarray = true;
11027
11028 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11029 {
11030 return false;
11031 }
11032
11033 if (size_and_type.first != npos)
11034 {
11035 if (size_and_type.second != 0)
11036 {
11037 if (size_and_type.second != 'N')
11038 {
11039 for (std::size_t i = 0; i < size_and_type.first; ++i)
11040 {
11041 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11042 {
11043 return false;
11044 }
11045 dim.push_back(dimlen);
11046 }
11047 }
11048 }
11049 else
11050 {
11051 for (std::size_t i = 0; i < size_and_type.first; ++i)
11052 {
11053 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11054 {
11055 return false;
11056 }
11057 dim.push_back(dimlen);
11058 }
11059 }
11060 }
11061 else
11062 {
11063 while (current != ']')
11064 {
11065 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11066 {
11067 return false;
11068 }
11069 dim.push_back(dimlen);
11070 get_ignore_noop();
11071 }
11072 }
11073 return true;
11074 }
11075
11087 bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11088 {
11089 if (prefix == 0)
11090 {
11091 prefix = get_ignore_noop();
11092 }
11093
11094 switch (prefix)
11095 {
11096 case 'U':
11097 {
11098 std::uint8_t number{};
11099 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11100 {
11101 return false;
11102 }
11103 result = static_cast<std::size_t>(number);
11104 return true;
11105 }
11106
11107 case 'i':
11108 {
11109 std::int8_t number{};
11110 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11111 {
11112 return false;
11113 }
11114 if (number < 0)
11115 {
11116 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11117 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11118 }
11119 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11120 return true;
11121 }
11122
11123 case 'I':
11124 {
11125 std::int16_t number{};
11126 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11127 {
11128 return false;
11129 }
11130 if (number < 0)
11131 {
11132 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11133 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11134 }
11135 result = static_cast<std::size_t>(number);
11136 return true;
11137 }
11138
11139 case 'l':
11140 {
11141 std::int32_t number{};
11142 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11143 {
11144 return false;
11145 }
11146 if (number < 0)
11147 {
11148 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11149 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11150 }
11151 result = static_cast<std::size_t>(number);
11152 return true;
11153 }
11154
11155 case 'L':
11156 {
11157 std::int64_t number{};
11158 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11159 {
11160 return false;
11161 }
11162 if (number < 0)
11163 {
11164 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11165 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11166 }
11167 if (!value_in_range_of<std::size_t>(number))
11168 {
11169 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11170 exception_message(input_format, "integer value overflow", "size"), nullptr));
11171 }
11172 result = static_cast<std::size_t>(number);
11173 return true;
11174 }
11175
11176 case 'u':
11177 {
11178 if (input_format != input_format_t::bjdata)
11179 {
11180 break;
11181 }
11182 std::uint16_t number{};
11183 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11184 {
11185 return false;
11186 }
11187 result = static_cast<std::size_t>(number);
11188 return true;
11189 }
11190
11191 case 'm':
11192 {
11193 if (input_format != input_format_t::bjdata)
11194 {
11195 break;
11196 }
11197 std::uint32_t number{};
11198 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11199 {
11200 return false;
11201 }
11202 result = conditional_static_cast<std::size_t>(number);
11203 return true;
11204 }
11205
11206 case 'M':
11207 {
11208 if (input_format != input_format_t::bjdata)
11209 {
11210 break;
11211 }
11212 std::uint64_t number{};
11213 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11214 {
11215 return false;
11216 }
11217 if (!value_in_range_of<std::size_t>(number))
11218 {
11219 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11220 exception_message(input_format, "integer value overflow", "size"), nullptr));
11221 }
11222 result = detail::conditional_static_cast<std::size_t>(number);
11223 return true;
11224 }
11225
11226 case '[':
11227 {
11228 if (input_format != input_format_t::bjdata)
11229 {
11230 break;
11231 }
11232 if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11233 {
11234 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr));
11235 }
11236 std::vector<size_t> dim;
11237 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11238 {
11239 return false;
11240 }
11241 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11242 {
11243 result = dim.at(dim.size() - 1);
11244 return true;
11245 }
11246 if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11247 {
11248 for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11249 {
11250 if (i == 0)
11251 {
11252 result = 0;
11253 return true;
11254 }
11255 }
11256
11257 string_t key = "_ArraySize_";
11258 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11259 {
11260 return false;
11261 }
11262 result = 1;
11263 for (auto i : dim)
11264 {
11265 result *= i;
11266 if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()
11267 {
11268 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
11269 }
11270 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11271 {
11272 return false;
11273 }
11274 }
11275 is_ndarray = true;
11276 return sax->end_array();
11277 }
11278 result = 0;
11279 return true;
11280 }
11281
11282 default:
11283 break;
11284 }
11285 auto last_token = get_token_string();
11286 std::string message;
11287
11288 if (input_format != input_format_t::bjdata)
11289 {
11290 message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11291 }
11292 else
11293 {
11294 message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11295 }
11296 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11297 }
11298
11310 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11311 {
11312 result.first = npos; // size
11313 result.second = 0; // type
11314 bool is_ndarray = false;
11315
11316 get_ignore_noop();
11317
11318 if (current == '$')
11319 {
11320 result.second = get(); // must not ignore 'N', because 'N' maybe the type
11321 if (input_format == input_format_t::bjdata
11322 && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
11323 {
11324 auto last_token = get_token_string();
11325 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11326 exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11327 }
11328
11329 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
11330 {
11331 return false;
11332 }
11333
11334 get_ignore_noop();
11335 if (JSON_HEDLEY_UNLIKELY(current != '#'))
11336 {
11337 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11338 {
11339 return false;
11340 }
11341 auto last_token = get_token_string();
11342 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11343 exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11344 }
11345
11346 const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11347 if (input_format == input_format_t::bjdata && is_ndarray)
11348 {
11349 if (inside_ndarray)
11350 {
11351 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11352 exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11353 }
11354 result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11355 }
11356 return is_error;
11357 }
11358
11359 if (current == '#')
11360 {
11361 const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11362 if (input_format == input_format_t::bjdata && is_ndarray)
11363 {
11364 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11365 exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11366 }
11367 return is_error;
11368 }
11369
11370 return true;
11371 }
11372
11377 bool get_ubjson_value(const char_int_type prefix)
11378 {
11379 switch (prefix)
11380 {
11381 case std::char_traits<char_type>::eof(): // EOF
11382 return unexpect_eof(input_format, "value");
11383
11384 case 'T': // true
11385 return sax->boolean(true);
11386 case 'F': // false
11387 return sax->boolean(false);
11388
11389 case 'Z': // null
11390 return sax->null();
11391
11392 case 'U':
11393 {
11394 std::uint8_t number{};
11395 return get_number(input_format, number) && sax->number_unsigned(number);
11396 }
11397
11398 case 'i':
11399 {
11400 std::int8_t number{};
11401 return get_number(input_format, number) && sax->number_integer(number);
11402 }
11403
11404 case 'I':
11405 {
11406 std::int16_t number{};
11407 return get_number(input_format, number) && sax->number_integer(number);
11408 }
11409
11410 case 'l':
11411 {
11412 std::int32_t number{};
11413 return get_number(input_format, number) && sax->number_integer(number);
11414 }
11415
11416 case 'L':
11417 {
11418 std::int64_t number{};
11419 return get_number(input_format, number) && sax->number_integer(number);
11420 }
11421
11422 case 'u':
11423 {
11424 if (input_format != input_format_t::bjdata)
11425 {
11426 break;
11427 }
11428 std::uint16_t number{};
11429 return get_number(input_format, number) && sax->number_unsigned(number);
11430 }
11431
11432 case 'm':
11433 {
11434 if (input_format != input_format_t::bjdata)
11435 {
11436 break;
11437 }
11438 std::uint32_t number{};
11439 return get_number(input_format, number) && sax->number_unsigned(number);
11440 }
11441
11442 case 'M':
11443 {
11444 if (input_format != input_format_t::bjdata)
11445 {
11446 break;
11447 }
11448 std::uint64_t number{};
11449 return get_number(input_format, number) && sax->number_unsigned(number);
11450 }
11451
11452 case 'h':
11453 {
11454 if (input_format != input_format_t::bjdata)
11455 {
11456 break;
11457 }
11458 const auto byte1_raw = get();
11459 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11460 {
11461 return false;
11462 }
11463 const auto byte2_raw = get();
11464 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11465 {
11466 return false;
11467 }
11468
11469 const auto byte1 = static_cast<unsigned char>(byte1_raw);
11470 const auto byte2 = static_cast<unsigned char>(byte2_raw);
11471
11472 // code from RFC 7049, Appendix D, Figure 3:
11473 // As half-precision floating-point numbers were only added
11474 // to IEEE 754 in 2008, today's programming platforms often
11475 // still only have limited support for them. It is very
11476 // easy to include at least decoding support for them even
11477 // without such support. An example of a small decoder for
11478 // half-precision floating-point numbers in the C language
11479 // is shown in Fig. 3.
11480 const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11481 const double val = [&half]
11482 {
11483 const int exp = (half >> 10u) & 0x1Fu;
11484 const unsigned int mant = half & 0x3FFu;
11485 JSON_ASSERT(0 <= exp && exp <= 32);
11486 JSON_ASSERT(mant <= 1024);
11487 switch (exp)
11488 {
11489 case 0:
11490 return std::ldexp(mant, -24);
11491 case 31:
11492 return (mant == 0)
11493 ? std::numeric_limits<double>::infinity()
11494 : std::numeric_limits<double>::quiet_NaN();
11495 default:
11496 return std::ldexp(mant + 1024, exp - 25);
11497 }
11498 }();
11499 return sax->number_float((half & 0x8000u) != 0
11500 ? static_cast<number_float_t>(-val)
11501 : static_cast<number_float_t>(val), "");
11502 }
11503
11504 case 'd':
11505 {
11506 float number{};
11507 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11508 }
11509
11510 case 'D':
11511 {
11512 double number{};
11513 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11514 }
11515
11516 case 'H':
11517 {
11518 return get_ubjson_high_precision_number();
11519 }
11520
11521 case 'C': // char
11522 {
11523 get();
11524 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11525 {
11526 return false;
11527 }
11528 if (JSON_HEDLEY_UNLIKELY(current > 127))
11529 {
11530 auto last_token = get_token_string();
11531 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11532 exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11533 }
11534 string_t s(1, static_cast<typename string_t::value_type>(current));
11535 return sax->string(s);
11536 }
11537
11538 case 'S': // string
11539 {
11540 string_t s;
11541 return get_ubjson_string(s) && sax->string(s);
11542 }
11543
11544 case '[': // array
11545 return get_ubjson_array();
11546
11547 case '{': // object
11548 return get_ubjson_object();
11549
11550 default: // anything else
11551 break;
11552 }
11553 auto last_token = get_token_string();
11554 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
11555 }
11556
11560 bool get_ubjson_array()
11561 {
11562 std::pair<std::size_t, char_int_type> size_and_type;
11563 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11564 {
11565 return false;
11566 }
11567
11568 // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
11569 // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11570
11571 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11572 {
11573 size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
11574 auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type& p, char_int_type t)
11575 {
11576 return p.first < t;
11577 });
11578 string_t key = "_ArrayType_";
11579 if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
11580 {
11581 auto last_token = get_token_string();
11582 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11583 exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11584 }
11585
11586 string_t type = it->second; // sax->string() takes a reference
11587 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
11588 {
11589 return false;
11590 }
11591
11592 if (size_and_type.second == 'C')
11593 {
11594 size_and_type.second = 'U';
11595 }
11596
11597 key = "_ArrayData_";
11598 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first)))
11599 {
11600 return false;
11601 }
11602
11603 for (std::size_t i = 0; i < size_and_type.first; ++i)
11604 {
11605 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11606 {
11607 return false;
11608 }
11609 }
11610
11611 return (sax->end_array() && sax->end_object());
11612 }
11613
11614 if (size_and_type.first != npos)
11615 {
11616 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11617 {
11618 return false;
11619 }
11620
11621 if (size_and_type.second != 0)
11622 {
11623 if (size_and_type.second != 'N')
11624 {
11625 for (std::size_t i = 0; i < size_and_type.first; ++i)
11626 {
11627 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11628 {
11629 return false;
11630 }
11631 }
11632 }
11633 }
11634 else
11635 {
11636 for (std::size_t i = 0; i < size_and_type.first; ++i)
11637 {
11638 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11639 {
11640 return false;
11641 }
11642 }
11643 }
11644 }
11645 else
11646 {
11647 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11648 {
11649 return false;
11650 }
11651
11652 while (current != ']')
11653 {
11654 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11655 {
11656 return false;
11657 }
11658 get_ignore_noop();
11659 }
11660 }
11661
11662 return sax->end_array();
11663 }
11664
11668 bool get_ubjson_object()
11669 {
11670 std::pair<std::size_t, char_int_type> size_and_type;
11671 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11672 {
11673 return false;
11674 }
11675
11676 // do not accept ND-array size in objects in BJData
11677 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11678 {
11679 auto last_token = get_token_string();
11680 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11681 exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11682 }
11683
11684 string_t key;
11685 if (size_and_type.first != npos)
11686 {
11687 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11688 {
11689 return false;
11690 }
11691
11692 if (size_and_type.second != 0)
11693 {
11694 for (std::size_t i = 0; i < size_and_type.first; ++i)
11695 {
11696 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11697 {
11698 return false;
11699 }
11700 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11701 {
11702 return false;
11703 }
11704 key.clear();
11705 }
11706 }
11707 else
11708 {
11709 for (std::size_t i = 0; i < size_and_type.first; ++i)
11710 {
11711 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11712 {
11713 return false;
11714 }
11715 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11716 {
11717 return false;
11718 }
11719 key.clear();
11720 }
11721 }
11722 }
11723 else
11724 {
11725 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11726 {
11727 return false;
11728 }
11729
11730 while (current != '}')
11731 {
11732 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11733 {
11734 return false;
11735 }
11736 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11737 {
11738 return false;
11739 }
11740 get_ignore_noop();
11741 key.clear();
11742 }
11743 }
11744
11745 return sax->end_object();
11746 }
11747
11748 // Note, no reader for UBJSON binary types is implemented because they do
11749 // not exist
11750
11751 bool get_ubjson_high_precision_number()
11752 {
11753 // get size of following number string
11754 std::size_t size{};
11755 bool no_ndarray = true;
11756 auto res = get_ubjson_size_value(size, no_ndarray);
11757 if (JSON_HEDLEY_UNLIKELY(!res))
11758 {
11759 return res;
11760 }
11761
11762 // get number string
11763 std::vector<char> number_vector;
11764 for (std::size_t i = 0; i < size; ++i)
11765 {
11766 get();
11767 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11768 {
11769 return false;
11770 }
11771 number_vector.push_back(static_cast<char>(current));
11772 }
11773
11774 // parse number string
11775 using ia_type = decltype(detail::input_adapter(number_vector));
11776 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11777 const auto result_number = number_lexer.scan();
11778 const auto number_string = number_lexer.get_token_string();
11779 const auto result_remainder = number_lexer.scan();
11780
11781 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11782
11783 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11784 {
11785 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11786 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11787 }
11788
11789 switch (result_number)
11790 {
11791 case token_type::value_integer:
11792 return sax->number_integer(number_lexer.get_number_integer());
11793 case token_type::value_unsigned:
11794 return sax->number_unsigned(number_lexer.get_number_unsigned());
11795 case token_type::value_float:
11796 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11797 case token_type::uninitialized:
11798 case token_type::literal_true:
11799 case token_type::literal_false:
11800 case token_type::literal_null:
11801 case token_type::value_string:
11802 case token_type::begin_array:
11803 case token_type::begin_object:
11804 case token_type::end_array:
11805 case token_type::end_object:
11806 case token_type::name_separator:
11807 case token_type::value_separator:
11808 case token_type::parse_error:
11809 case token_type::end_of_input:
11810 case token_type::literal_or_value:
11811 default:
11812 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11813 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11814 }
11815 }
11816
11818 // Utility functions //
11820
11830 char_int_type get()
11831 {
11832 ++chars_read;
11833 return current = ia.get_character();
11834 }
11835
11839 char_int_type get_ignore_noop()
11840 {
11841 do
11842 {
11843 get();
11844 } while (current == 'N');
11845
11846 return current;
11847 }
11848
11849 /*
11850 @brief read a number from the input
11851
11852 @tparam NumberType the type of the number
11853 @param[in] format the current format (for diagnostics)
11854 @param[out] result number of type @a NumberType
11855
11856 @return whether conversion completed
11857
11858 @note This function needs to respect the system's endianness, because
11859 bytes in CBOR, MessagePack, and UBJSON are stored in network order
11860 (big endian) and therefore need reordering on little endian systems.
11861 On the other hand, BSON and BJData use little endian and should reorder
11862 on big endian systems.
11863 */
11864 template<typename NumberType, bool InputIsLittleEndian = false>
11865 bool get_number(const input_format_t format, NumberType& result)
11866 {
11867 // step 1: read input into array with system's byte order
11868 std::array<std::uint8_t, sizeof(NumberType)> vec{};
11869 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11870 {
11871 get();
11872 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11873 {
11874 return false;
11875 }
11876
11877 // reverse byte order prior to conversion if necessary
11878 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11879 {
11880 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11881 }
11882 else
11883 {
11884 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11885 }
11886 }
11887
11888 // step 2: convert array into number of type T and return
11889 std::memcpy(&result, vec.data(), sizeof(NumberType));
11890 return true;
11891 }
11892
11907 template<typename NumberType>
11908 bool get_string(const input_format_t format,
11909 const NumberType len,
11910 string_t& result)
11911 {
11912 bool success = true;
11913 for (NumberType i = 0; i < len; i++)
11914 {
11915 get();
11916 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11917 {
11918 success = false;
11919 break;
11920 }
11921 result.push_back(static_cast<typename string_t::value_type>(current));
11922 }
11923 return success;
11924 }
11925
11940 template<typename NumberType>
11941 bool get_binary(const input_format_t format,
11942 const NumberType len,
11943 binary_t& result)
11944 {
11945 bool success = true;
11946 for (NumberType i = 0; i < len; i++)
11947 {
11948 get();
11949 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11950 {
11951 success = false;
11952 break;
11953 }
11954 result.push_back(static_cast<std::uint8_t>(current));
11955 }
11956 return success;
11957 }
11958
11965 bool unexpect_eof(const input_format_t format, const char* context) const
11966 {
11967 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11968 {
11969 return sax->parse_error(chars_read, "<end of file>",
11970 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11971 }
11972 return true;
11973 }
11974
11978 std::string get_token_string() const
11979 {
11980 std::array<char, 3> cr{ {} };
11981 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11982 return std::string{ cr.data() };
11983 }
11984
11991 std::string exception_message(const input_format_t format,
11992 const std::string& detail,
11993 const std::string& context) const
11994 {
11995 std::string error_msg = "syntax error while parsing ";
11996
11997 switch (format)
11998 {
12000 error_msg += "CBOR";
12001 break;
12002
12004 error_msg += "MessagePack";
12005 break;
12006
12008 error_msg += "UBJSON";
12009 break;
12010
12012 error_msg += "BSON";
12013 break;
12014
12016 error_msg += "BJData";
12017 break;
12018
12019 case input_format_t::json: // LCOV_EXCL_LINE
12020 default: // LCOV_EXCL_LINE
12021 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12022 }
12023
12024 return concat(error_msg, ' ', context, ": ", detail);
12025 }
12026
12027 private:
12028 static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);
12029
12031 InputAdapterType ia;
12032
12034 char_int_type current = std::char_traits<char_type>::eof();
12035
12037 std::size_t chars_read = 0;
12038
12040 const bool is_little_endian = little_endianness();
12041
12043 const input_format_t input_format = input_format_t::json;
12044
12046 json_sax_t* sax = nullptr;
12047
12048 // excluded markers in bjdata optimized type
12049#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12050 make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12051
12052#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12053 make_array<bjd_type>( \
12054 bjd_type{'C', "char"}, \
12055 bjd_type{'D', "double"}, \
12056 bjd_type{'I', "int16"}, \
12057 bjd_type{'L', "int64"}, \
12058 bjd_type{'M', "uint64"}, \
12059 bjd_type{'U', "uint8"}, \
12060 bjd_type{'d', "single"}, \
12061 bjd_type{'i', "int8"}, \
12062 bjd_type{'l', "int32"}, \
12063 bjd_type{'m', "uint32"}, \
12064 bjd_type{'u', "uint16"})
12065
12067 // lookup tables
12068 // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12069 const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12071
12072 using bjd_type = std::pair<char_int_type, string_t>;
12073 // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12074 const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12076
12077#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12078#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12079 };
12080
12081#ifndef JSON_HAS_CPP_17
12082 template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12083 constexpr std::size_t binary_reader<BasicJsonType, InputAdapterType, SAX>::npos;
12084#endif
12085
12086} // namespace detail
12088
12089// #include <nlohmann/detail/input/input_adapters.hpp>
12090
12091// #include <nlohmann/detail/input/lexer.hpp>
12092
12093// #include <nlohmann/detail/input/parser.hpp>
12094// __ _____ _____ _____
12095// __| | __| | | | JSON for Modern C++
12096// | | |__ | | | | | | version 3.11.2
12097// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12098//
12099// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12100// SPDX-License-Identifier: MIT
12101
12102
12103
12104#include <cmath> // isfinite
12105#include <cstdint> // uint8_t
12106#include <functional> // function
12107#include <string> // string
12108#include <utility> // move
12109#include <vector> // vector
12110
12111// #include <nlohmann/detail/exceptions.hpp>
12112
12113// #include <nlohmann/detail/input/input_adapters.hpp>
12114
12115// #include <nlohmann/detail/input/json_sax.hpp>
12116
12117// #include <nlohmann/detail/input/lexer.hpp>
12118
12119// #include <nlohmann/detail/macro_scope.hpp>
12120
12121// #include <nlohmann/detail/meta/is_sax.hpp>
12122
12123// #include <nlohmann/detail/string_concat.hpp>
12124
12125// #include <nlohmann/detail/value_t.hpp>
12126
12127
12129namespace detail
12130{
12132 // parser //
12134
12135 enum class parse_event_t : std::uint8_t
12136 {
12140 object_end,
12144 array_end,
12146 key,
12148 value
12149 };
12150
12151 template<typename BasicJsonType>
12153 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12154
12160 template<typename BasicJsonType, typename InputAdapterType>
12162 {
12163 using number_integer_t = typename BasicJsonType::number_integer_t;
12164 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12165 using number_float_t = typename BasicJsonType::number_float_t;
12166 using string_t = typename BasicJsonType::string_t;
12168 using token_type = typename lexer_t::token_type;
12169
12170 public:
12172 explicit parser(InputAdapterType&& adapter,
12173 const parser_callback_t<BasicJsonType> cb = nullptr,
12174 const bool allow_exceptions_ = true,
12175 const bool skip_comments = false)
12176 : callback(cb)
12177 , m_lexer(std::move(adapter), skip_comments)
12178 , allow_exceptions(allow_exceptions_)
12179 {
12180 // read first token
12181 get_token();
12182 }
12183
12194 void parse(const bool strict, BasicJsonType& result)
12195 {
12196 if (callback)
12197 {
12198 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
12199 sax_parse_internal(&sdp);
12200
12201 // in strict mode, input must be completely read
12202 if (strict && (get_token() != token_type::end_of_input))
12203 {
12204 sdp.parse_error(m_lexer.get_position(),
12205 m_lexer.get_token_string(),
12206 parse_error::create(101, m_lexer.get_position(),
12207 exception_message(token_type::end_of_input, "value"), nullptr));
12208 }
12209
12210 // in case of an error, return discarded value
12211 if (sdp.is_errored())
12212 {
12213 result = value_t::discarded;
12214 return;
12215 }
12216
12217 // set top-level value to null if it was discarded by the callback
12218 // function
12219 if (result.is_discarded())
12220 {
12221 result = nullptr;
12222 }
12223 }
12224 else
12225 {
12226 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
12227 sax_parse_internal(&sdp);
12228
12229 // in strict mode, input must be completely read
12230 if (strict && (get_token() != token_type::end_of_input))
12231 {
12232 sdp.parse_error(m_lexer.get_position(),
12233 m_lexer.get_token_string(),
12234 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12235 }
12236
12237 // in case of an error, return discarded value
12238 if (sdp.is_errored())
12239 {
12240 result = value_t::discarded;
12241 return;
12242 }
12243 }
12244
12245 result.assert_invariant();
12246 }
12247
12254 bool accept(const bool strict = true)
12255 {
12257 return sax_parse(&sax_acceptor, strict);
12258 }
12259
12260 template<typename SAX>
12262 bool sax_parse(SAX* sax, const bool strict = true)
12263 {
12265 const bool result = sax_parse_internal(sax);
12266
12267 // strict mode: next byte must be EOF
12268 if (result && strict && (get_token() != token_type::end_of_input))
12269 {
12270 return sax->parse_error(m_lexer.get_position(),
12271 m_lexer.get_token_string(),
12272 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12273 }
12274
12275 return result;
12276 }
12277
12278 private:
12279 template<typename SAX>
12281 bool sax_parse_internal(SAX* sax)
12282 {
12283 // stack to remember the hierarchy of structured values we are parsing
12284 // true = array; false = object
12285 std::vector<bool> states;
12286 // value to avoid a goto (see comment where set to true)
12287 bool skip_to_state_evaluation = false;
12288
12289 while (true)
12290 {
12291 if (!skip_to_state_evaluation)
12292 {
12293 // invariant: get_token() was called before each iteration
12294 switch (last_token)
12295 {
12296 case token_type::begin_object:
12297 {
12298 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12299 {
12300 return false;
12301 }
12302
12303 // closing } -> we are done
12304 if (get_token() == token_type::end_object)
12305 {
12306 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12307 {
12308 return false;
12309 }
12310 break;
12311 }
12312
12313 // parse key
12314 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12315 {
12316 return sax->parse_error(m_lexer.get_position(),
12317 m_lexer.get_token_string(),
12318 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12319 }
12320 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12321 {
12322 return false;
12323 }
12324
12325 // parse separator (:)
12326 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12327 {
12328 return sax->parse_error(m_lexer.get_position(),
12329 m_lexer.get_token_string(),
12330 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12331 }
12332
12333 // remember we are now inside an object
12334 states.push_back(false);
12335
12336 // parse values
12337 get_token();
12338 continue;
12339 }
12340
12341 case token_type::begin_array:
12342 {
12343 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12344 {
12345 return false;
12346 }
12347
12348 // closing ] -> we are done
12349 if (get_token() == token_type::end_array)
12350 {
12351 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12352 {
12353 return false;
12354 }
12355 break;
12356 }
12357
12358 // remember we are now inside an array
12359 states.push_back(true);
12360
12361 // parse values (no need to call get_token)
12362 continue;
12363 }
12364
12365 case token_type::value_float:
12366 {
12367 const auto res = m_lexer.get_number_float();
12368
12369 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12370 {
12371 return sax->parse_error(m_lexer.get_position(),
12372 m_lexer.get_token_string(),
12373 out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12374 }
12375
12376 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12377 {
12378 return false;
12379 }
12380
12381 break;
12382 }
12383
12384 case token_type::literal_false:
12385 {
12386 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12387 {
12388 return false;
12389 }
12390 break;
12391 }
12392
12393 case token_type::literal_null:
12394 {
12395 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12396 {
12397 return false;
12398 }
12399 break;
12400 }
12401
12402 case token_type::literal_true:
12403 {
12404 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12405 {
12406 return false;
12407 }
12408 break;
12409 }
12410
12411 case token_type::value_integer:
12412 {
12413 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12414 {
12415 return false;
12416 }
12417 break;
12418 }
12419
12420 case token_type::value_string:
12421 {
12422 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12423 {
12424 return false;
12425 }
12426 break;
12427 }
12428
12429 case token_type::value_unsigned:
12430 {
12431 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12432 {
12433 return false;
12434 }
12435 break;
12436 }
12437
12438 case token_type::parse_error:
12439 {
12440 // using "uninitialized" to avoid "expected" message
12441 return sax->parse_error(m_lexer.get_position(),
12442 m_lexer.get_token_string(),
12443 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12444 }
12445
12446 case token_type::uninitialized:
12447 case token_type::end_array:
12448 case token_type::end_object:
12449 case token_type::name_separator:
12450 case token_type::value_separator:
12451 case token_type::end_of_input:
12452 case token_type::literal_or_value:
12453 default: // the last token was unexpected
12454 {
12455 return sax->parse_error(m_lexer.get_position(),
12456 m_lexer.get_token_string(),
12457 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12458 }
12459 }
12460 }
12461 else
12462 {
12463 skip_to_state_evaluation = false;
12464 }
12465
12466 // we reached this line after we successfully parsed a value
12467 if (states.empty())
12468 {
12469 // empty stack: we reached the end of the hierarchy: done
12470 return true;
12471 }
12472
12473 if (states.back()) // array
12474 {
12475 // comma -> next value
12476 if (get_token() == token_type::value_separator)
12477 {
12478 // parse a new value
12479 get_token();
12480 continue;
12481 }
12482
12483 // closing ]
12484 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12485 {
12486 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12487 {
12488 return false;
12489 }
12490
12491 // We are done with this array. Before we can parse a
12492 // new value, we need to evaluate the new state first.
12493 // By setting skip_to_state_evaluation to false, we
12494 // are effectively jumping to the beginning of this if.
12495 JSON_ASSERT(!states.empty());
12496 states.pop_back();
12497 skip_to_state_evaluation = true;
12498 continue;
12499 }
12500
12501 return sax->parse_error(m_lexer.get_position(),
12502 m_lexer.get_token_string(),
12503 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12504 }
12505
12506 // states.back() is false -> object
12507
12508 // comma -> next value
12509 if (get_token() == token_type::value_separator)
12510 {
12511 // parse key
12512 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12513 {
12514 return sax->parse_error(m_lexer.get_position(),
12515 m_lexer.get_token_string(),
12516 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12517 }
12518
12519 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12520 {
12521 return false;
12522 }
12523
12524 // parse separator (:)
12525 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12526 {
12527 return sax->parse_error(m_lexer.get_position(),
12528 m_lexer.get_token_string(),
12529 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12530 }
12531
12532 // parse values
12533 get_token();
12534 continue;
12535 }
12536
12537 // closing }
12538 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12539 {
12540 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12541 {
12542 return false;
12543 }
12544
12545 // We are done with this object. Before we can parse a
12546 // new value, we need to evaluate the new state first.
12547 // By setting skip_to_state_evaluation to false, we
12548 // are effectively jumping to the beginning of this if.
12549 JSON_ASSERT(!states.empty());
12550 states.pop_back();
12551 skip_to_state_evaluation = true;
12552 continue;
12553 }
12554
12555 return sax->parse_error(m_lexer.get_position(),
12556 m_lexer.get_token_string(),
12557 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12558 }
12559 }
12560
12562 token_type get_token()
12563 {
12564 return last_token = m_lexer.scan();
12565 }
12566
12567 std::string exception_message(const token_type expected, const std::string& context)
12568 {
12569 std::string error_msg = "syntax error ";
12570
12571 if (!context.empty())
12572 {
12573 error_msg += concat("while parsing ", context, ' ');
12574 }
12575
12576 error_msg += "- ";
12577
12578 if (last_token == token_type::parse_error)
12579 {
12580 error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12581 m_lexer.get_token_string(), '\'');
12582 }
12583 else
12584 {
12585 error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12586 }
12587
12588 if (expected != token_type::uninitialized)
12589 {
12590 error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12591 }
12592
12593 return error_msg;
12594 }
12595
12596 private:
12598 const parser_callback_t<BasicJsonType> callback = nullptr;
12600 token_type last_token = token_type::uninitialized;
12602 lexer_t m_lexer;
12604 const bool allow_exceptions = true;
12605 };
12606
12607} // namespace detail
12609
12610// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12611// __ _____ _____ _____
12612// __| | __| | | | JSON for Modern C++
12613// | | |__ | | | | | | version 3.11.2
12614// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12615//
12616// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12617// SPDX-License-Identifier: MIT
12618
12619
12620
12621// #include <nlohmann/detail/abi_macros.hpp>
12622
12623// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12624// __ _____ _____ _____
12625// __| | __| | | | JSON for Modern C++
12626// | | |__ | | | | | | version 3.11.2
12627// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12628//
12629// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12630// SPDX-License-Identifier: MIT
12631
12632
12633
12634#include <cstddef> // ptrdiff_t
12635#include <limits> // numeric_limits
12636
12637// #include <nlohmann/detail/macro_scope.hpp>
12638
12639
12641namespace detail
12642{
12643
12644 /*
12645 @brief an iterator for primitive JSON types
12646
12647 This class models an iterator for primitive JSON types (boolean, number,
12648 string). It's only purpose is to allow the iterator/const_iterator classes
12649 to "iterate" over primitive values. Internally, the iterator is modeled by
12650 a `difference_type` variable. Value begin_value (`0`) models the begin,
12651 end_value (`1`) models past the end.
12652 */
12654 {
12655 private:
12656 using difference_type = std::ptrdiff_t;
12657 static constexpr difference_type begin_value = 0;
12658 static constexpr difference_type end_value = begin_value + 1;
12659
12662 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12663
12664 public:
12665 constexpr difference_type get_value() const noexcept
12666 {
12667 return m_it;
12668 }
12669
12671 void set_begin() noexcept
12672 {
12673 m_it = begin_value;
12674 }
12675
12677 void set_end() noexcept
12678 {
12679 m_it = end_value;
12680 }
12681
12683 constexpr bool is_begin() const noexcept
12684 {
12685 return m_it == begin_value;
12686 }
12687
12689 constexpr bool is_end() const noexcept
12690 {
12691 return m_it == end_value;
12692 }
12693
12694 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12695 {
12696 return lhs.m_it == rhs.m_it;
12697 }
12698
12699 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12700 {
12701 return lhs.m_it < rhs.m_it;
12702 }
12703
12704 primitive_iterator_t operator+(difference_type n) noexcept
12705 {
12706 auto result = *this;
12707 result += n;
12708 return result;
12709 }
12710
12711 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12712 {
12713 return lhs.m_it - rhs.m_it;
12714 }
12715
12717 {
12718 ++m_it;
12719 return *this;
12720 }
12721
12722 primitive_iterator_t operator++(int)&noexcept // NOLINT(cert-dcl21-cpp)
12723 {
12724 auto result = *this;
12725 ++m_it;
12726 return result;
12727 }
12728
12730 {
12731 --m_it;
12732 return *this;
12733 }
12734
12735 primitive_iterator_t operator--(int)&noexcept // NOLINT(cert-dcl21-cpp)
12736 {
12737 auto result = *this;
12738 --m_it;
12739 return result;
12740 }
12741
12742 primitive_iterator_t& operator+=(difference_type n) noexcept
12743 {
12744 m_it += n;
12745 return *this;
12746 }
12747
12748 primitive_iterator_t& operator-=(difference_type n) noexcept
12749 {
12750 m_it -= n;
12751 return *this;
12752 }
12753 };
12754
12755} // namespace detail
12757
12758
12760namespace detail
12761{
12762
12769 template<typename BasicJsonType> struct internal_iterator
12770 {
12772 typename BasicJsonType::object_t::iterator object_iterator{};
12774 typename BasicJsonType::array_t::iterator array_iterator{};
12777 };
12778
12779} // namespace detail
12781
12782// #include <nlohmann/detail/iterators/iter_impl.hpp>
12783// __ _____ _____ _____
12784// __| | __| | | | JSON for Modern C++
12785// | | |__ | | | | | | version 3.11.2
12786// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12787//
12788// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12789// SPDX-License-Identifier: MIT
12790
12791
12792
12793#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12794#include <type_traits> // conditional, is_const, remove_const
12795
12796// #include <nlohmann/detail/exceptions.hpp>
12797
12798// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12799
12800// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12801
12802// #include <nlohmann/detail/macro_scope.hpp>
12803
12804// #include <nlohmann/detail/meta/cpp_future.hpp>
12805
12806// #include <nlohmann/detail/meta/type_traits.hpp>
12807
12808// #include <nlohmann/detail/value_t.hpp>
12809
12810
12812namespace detail
12813{
12814
12815 // forward declare, to be able to friend it later on
12816 template<typename IteratorType> class iteration_proxy;
12817 template<typename IteratorType> class iteration_proxy_value;
12818
12835 template<typename BasicJsonType>
12836 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12837 {
12839 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12841 friend other_iter_impl;
12842 friend BasicJsonType;
12845
12846 using object_t = typename BasicJsonType::object_t;
12847 using array_t = typename BasicJsonType::array_t;
12848 // make sure BasicJsonType is basic_json or const basic_json
12850 "iter_impl only accepts (const) basic_json");
12851 // superficial check for the LegacyBidirectionalIterator named requirement
12852 static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12853 && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12854 "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12855
12856 public:
12862 using iterator_category = std::bidirectional_iterator_tag;
12863
12865 using value_type = typename BasicJsonType::value_type;
12867 using difference_type = typename BasicJsonType::difference_type;
12869 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12870 typename BasicJsonType::const_pointer,
12871 typename BasicJsonType::pointer>::type;
12874 typename std::conditional<std::is_const<BasicJsonType>::value,
12875 typename BasicJsonType::const_reference,
12876 typename BasicJsonType::reference>::type;
12877
12878 iter_impl() = default;
12879 ~iter_impl() = default;
12880 iter_impl(iter_impl&&) noexcept = default;
12881 iter_impl& operator=(iter_impl&&) noexcept = default;
12882
12889 explicit iter_impl(pointer object) noexcept : m_object(object)
12890 {
12891 JSON_ASSERT(m_object != nullptr);
12892
12893 switch (m_object->m_data.m_type)
12894 {
12895 case value_t::object:
12896 {
12897 m_it.object_iterator = typename object_t::iterator();
12898 break;
12899 }
12900
12901 case value_t::array:
12902 {
12903 m_it.array_iterator = typename array_t::iterator();
12904 break;
12905 }
12906
12907 case value_t::null:
12908 case value_t::string:
12909 case value_t::boolean:
12913 case value_t::binary:
12914 case value_t::discarded:
12915 default:
12916 {
12918 break;
12919 }
12920 }
12921 }
12922
12940 : m_object(other.m_object), m_it(other.m_it)
12941 {}
12942
12950 {
12951 if (&other != this)
12952 {
12953 m_object = other.m_object;
12954 m_it = other.m_it;
12955 }
12956 return *this;
12957 }
12958
12964 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
12965 : m_object(other.m_object), m_it(other.m_it)
12966 {}
12967
12974 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12975 {
12976 m_object = other.m_object;
12977 m_it = other.m_it;
12978 return *this;
12979 }
12980
12986 void set_begin() noexcept
12987 {
12988 JSON_ASSERT(m_object != nullptr);
12989
12990 switch (m_object->m_data.m_type)
12991 {
12992 case value_t::object:
12993 {
12994 m_it.object_iterator = m_object->m_data.m_value.object->begin();
12995 break;
12996 }
12997
12998 case value_t::array:
12999 {
13000 m_it.array_iterator = m_object->m_data.m_value.array->begin();
13001 break;
13002 }
13003
13004 case value_t::null:
13005 {
13006 // set to end so begin()==end() is true: null is empty
13008 break;
13009 }
13010
13011 case value_t::string:
13012 case value_t::boolean:
13016 case value_t::binary:
13017 case value_t::discarded:
13018 default:
13019 {
13021 break;
13022 }
13023 }
13024 }
13025
13030 void set_end() noexcept
13031 {
13032 JSON_ASSERT(m_object != nullptr);
13033
13034 switch (m_object->m_data.m_type)
13035 {
13036 case value_t::object:
13037 {
13038 m_it.object_iterator = m_object->m_data.m_value.object->end();
13039 break;
13040 }
13041
13042 case value_t::array:
13043 {
13044 m_it.array_iterator = m_object->m_data.m_value.array->end();
13045 break;
13046 }
13047
13048 case value_t::null:
13049 case value_t::string:
13050 case value_t::boolean:
13054 case value_t::binary:
13055 case value_t::discarded:
13056 default:
13057 {
13059 break;
13060 }
13061 }
13062 }
13063
13064 public:
13070 {
13071 JSON_ASSERT(m_object != nullptr);
13072
13073 switch (m_object->m_data.m_type)
13074 {
13075 case value_t::object:
13076 {
13077 JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13078 return m_it.object_iterator->second;
13079 }
13080
13081 case value_t::array:
13082 {
13083 JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13084 return *m_it.array_iterator;
13085 }
13086
13087 case value_t::null:
13088 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13089
13090 case value_t::string:
13091 case value_t::boolean:
13095 case value_t::binary:
13096 case value_t::discarded:
13097 default:
13098 {
13100 {
13101 return *m_object;
13102 }
13103
13104 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13105 }
13106 }
13107 }
13108
13114 {
13115 JSON_ASSERT(m_object != nullptr);
13116
13117 switch (m_object->m_data.m_type)
13118 {
13119 case value_t::object:
13120 {
13121 JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13122 return &(m_it.object_iterator->second);
13123 }
13124
13125 case value_t::array:
13126 {
13127 JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13128 return &*m_it.array_iterator;
13129 }
13130
13131 case value_t::null:
13132 case value_t::string:
13133 case value_t::boolean:
13137 case value_t::binary:
13138 case value_t::discarded:
13139 default:
13140 {
13142 {
13143 return m_object;
13144 }
13145
13146 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13147 }
13148 }
13149 }
13150
13155 iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13156 {
13157 auto result = *this;
13158 ++(*this);
13159 return result;
13160 }
13161
13167 {
13168 JSON_ASSERT(m_object != nullptr);
13169
13170 switch (m_object->m_data.m_type)
13171 {
13172 case value_t::object:
13173 {
13174 std::advance(m_it.object_iterator, 1);
13175 break;
13176 }
13177
13178 case value_t::array:
13179 {
13180 std::advance(m_it.array_iterator, 1);
13181 break;
13182 }
13183
13184 case value_t::null:
13185 case value_t::string:
13186 case value_t::boolean:
13190 case value_t::binary:
13191 case value_t::discarded:
13192 default:
13193 {
13195 break;
13196 }
13197 }
13198
13199 return *this;
13200 }
13201
13206 iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13207 {
13208 auto result = *this;
13209 --(*this);
13210 return result;
13211 }
13212
13218 {
13219 JSON_ASSERT(m_object != nullptr);
13220
13221 switch (m_object->m_data.m_type)
13222 {
13223 case value_t::object:
13224 {
13225 std::advance(m_it.object_iterator, -1);
13226 break;
13227 }
13228
13229 case value_t::array:
13230 {
13231 std::advance(m_it.array_iterator, -1);
13232 break;
13233 }
13234
13235 case value_t::null:
13236 case value_t::string:
13237 case value_t::boolean:
13241 case value_t::binary:
13242 case value_t::discarded:
13243 default:
13244 {
13246 break;
13247 }
13248 }
13249
13250 return *this;
13251 }
13252
13257 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13258 bool operator==(const IterImpl& other) const
13259 {
13260 // if objects are not the same, the comparison is undefined
13261 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13262 {
13263 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13264 }
13265
13266 JSON_ASSERT(m_object != nullptr);
13267
13268 switch (m_object->m_data.m_type)
13269 {
13270 case value_t::object:
13271 return (m_it.object_iterator == other.m_it.object_iterator);
13272
13273 case value_t::array:
13274 return (m_it.array_iterator == other.m_it.array_iterator);
13275
13276 case value_t::null:
13277 case value_t::string:
13278 case value_t::boolean:
13282 case value_t::binary:
13283 case value_t::discarded:
13284 default:
13285 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13286 }
13287 }
13288
13293 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13294 bool operator!=(const IterImpl& other) const
13295 {
13296 return !operator==(other);
13297 }
13298
13303 bool operator<(const iter_impl& other) const
13304 {
13305 // if objects are not the same, the comparison is undefined
13306 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13307 {
13308 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13309 }
13310
13311 JSON_ASSERT(m_object != nullptr);
13312
13313 switch (m_object->m_data.m_type)
13314 {
13315 case value_t::object:
13316 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13317
13318 case value_t::array:
13319 return (m_it.array_iterator < other.m_it.array_iterator);
13320
13321 case value_t::null:
13322 case value_t::string:
13323 case value_t::boolean:
13327 case value_t::binary:
13328 case value_t::discarded:
13329 default:
13331 }
13332 }
13333
13338 bool operator<=(const iter_impl& other) const
13339 {
13340 return !other.operator < (*this);
13341 }
13342
13347 bool operator>(const iter_impl& other) const
13348 {
13349 return !operator<=(other);
13350 }
13351
13356 bool operator>=(const iter_impl& other) const
13357 {
13358 return !operator<(other);
13359 }
13360
13366 {
13367 JSON_ASSERT(m_object != nullptr);
13368
13369 switch (m_object->m_data.m_type)
13370 {
13371 case value_t::object:
13372 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13373
13374 case value_t::array:
13375 {
13376 std::advance(m_it.array_iterator, i);
13377 break;
13378 }
13379
13380 case value_t::null:
13381 case value_t::string:
13382 case value_t::boolean:
13386 case value_t::binary:
13387 case value_t::discarded:
13388 default:
13389 {
13391 break;
13392 }
13393 }
13394
13395 return *this;
13396 }
13397
13403 {
13404 return operator+=(-i);
13405 }
13406
13412 {
13413 auto result = *this;
13414 result += i;
13415 return result;
13416 }
13417
13423 {
13424 auto result = it;
13425 result += i;
13426 return result;
13427 }
13428
13434 {
13435 auto result = *this;
13436 result -= i;
13437 return result;
13438 }
13439
13445 {
13446 JSON_ASSERT(m_object != nullptr);
13447
13448 switch (m_object->m_data.m_type)
13449 {
13450 case value_t::object:
13451 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13452
13453 case value_t::array:
13454 return m_it.array_iterator - other.m_it.array_iterator;
13455
13456 case value_t::null:
13457 case value_t::string:
13458 case value_t::boolean:
13462 case value_t::binary:
13463 case value_t::discarded:
13464 default:
13466 }
13467 }
13468
13474 {
13475 JSON_ASSERT(m_object != nullptr);
13476
13477 switch (m_object->m_data.m_type)
13478 {
13479 case value_t::object:
13480 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13481
13482 case value_t::array:
13483 return *std::next(m_it.array_iterator, n);
13484
13485 case value_t::null:
13486 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13487
13488 case value_t::string:
13489 case value_t::boolean:
13493 case value_t::binary:
13494 case value_t::discarded:
13495 default:
13496 {
13498 {
13499 return *m_object;
13500 }
13501
13502 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13503 }
13504 }
13505 }
13506
13511 const typename object_t::key_type& key() const
13512 {
13513 JSON_ASSERT(m_object != nullptr);
13514
13515 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13516 {
13517 return m_it.object_iterator->first;
13518 }
13519
13520 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13521 }
13522
13528 {
13529 return operator*();
13530 }
13531
13534 pointer m_object = nullptr;
13537 };
13538
13539} // namespace detail
13541
13542// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13543
13544// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13545// __ _____ _____ _____
13546// __| | __| | | | JSON for Modern C++
13547// | | |__ | | | | | | version 3.11.2
13548// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13549//
13550// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13551// SPDX-License-Identifier: MIT
13552
13553
13554
13555#include <cstddef> // ptrdiff_t
13556#include <iterator> // reverse_iterator
13557#include <utility> // declval
13558
13559// #include <nlohmann/detail/abi_macros.hpp>
13560
13561
13563namespace detail
13564{
13565
13567 // reverse_iterator //
13569
13588 template<typename Base>
13589 class json_reverse_iterator : public std::reverse_iterator<Base>
13590 {
13591 public:
13592 using difference_type = std::ptrdiff_t;
13594 using base_iterator = std::reverse_iterator<Base>;
13596 using reference = typename Base::reference;
13597
13599 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13600 : base_iterator(it) {}
13601
13603 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13604
13606 json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13607 {
13608 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13609 }
13610
13613 {
13614 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13615 }
13616
13618 json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13619 {
13620 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13621 }
13622
13625 {
13626 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13627 }
13628
13631 {
13632 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13633 }
13634
13637 {
13638 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13639 }
13640
13643 {
13644 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13645 }
13646
13649 {
13650 return base_iterator(*this) - base_iterator(other);
13651 }
13652
13655 {
13656 return *(this->operator+(n));
13657 }
13658
13660 auto key() const -> decltype(std::declval<Base>().key())
13661 {
13662 auto it = --this->base();
13663 return it.key();
13664 }
13665
13668 {
13669 auto it = --this->base();
13670 return it.operator * ();
13671 }
13672 };
13673
13674} // namespace detail
13676
13677// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13678
13679// #include <nlohmann/detail/json_custom_base_class.hpp>
13680
13681
13682#include <type_traits> // conditional, is_same
13683
13684// #include <nlohmann/detail/abi_macros.hpp>
13685
13686
13688namespace detail
13689{
13690
13702
13703 template<class T>
13704 using json_base_class = typename std::conditional <
13705 std::is_same<T, void>::value,
13707 T
13708 >::type;
13709
13710} // namespace detail
13712
13713// #include <nlohmann/detail/json_pointer.hpp>
13714// __ _____ _____ _____
13715// __| | __| | | | JSON for Modern C++
13716// | | |__ | | | | | | version 3.11.2
13717// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13718//
13719// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13720// SPDX-License-Identifier: MIT
13721
13722
13723
13724#include <algorithm> // all_of
13725#include <cctype> // isdigit
13726#include <cerrno> // errno, ERANGE
13727#include <cstdlib> // strtoull
13728#ifndef JSON_NO_IO
13729#include <iosfwd> // ostream
13730#endif // JSON_NO_IO
13731#include <limits> // max
13732#include <numeric> // accumulate
13733#include <string> // string
13734#include <utility> // move
13735#include <vector> // vector
13736
13737// #include <nlohmann/detail/exceptions.hpp>
13738
13739// #include <nlohmann/detail/macro_scope.hpp>
13740
13741// #include <nlohmann/detail/string_concat.hpp>
13742
13743// #include <nlohmann/detail/string_escape.hpp>
13744
13745// #include <nlohmann/detail/value_t.hpp>
13746
13747
13749
13752template<typename RefStringType>
13754{
13755 // allow basic_json to access private members
13757 friend class basic_json;
13758
13759 template<typename>
13760 friend class json_pointer;
13761
13762 template<typename T>
13763 struct string_t_helper
13764 {
13765 using type = T;
13766 };
13767
13769 struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
13770 {
13771 using type = StringType;
13772 };
13773
13774public:
13775 // for backwards compatibility accept BasicJsonType
13776 using string_t = typename string_t_helper<RefStringType>::type;
13777
13780 explicit json_pointer(const string_t& s = "")
13781 : reference_tokens(split(s))
13782 {}
13783
13787 {
13788 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13789 string_t{},
13790 [](const string_t& a, const string_t& b)
13791 {
13792 return detail::concat(a, '/', detail::escape(b));
13793 });
13794 }
13795
13799 operator string_t() const
13800 {
13801 return to_string();
13802 }
13803
13804#ifndef JSON_NO_IO
13807 friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13808 {
13809 o << ptr.to_string();
13810 return o;
13811 }
13812#endif
13813
13817 {
13818 reference_tokens.insert(reference_tokens.end(),
13819 ptr.reference_tokens.begin(),
13820 ptr.reference_tokens.end());
13821 return *this;
13822 }
13823
13827 {
13828 push_back(std::move(token));
13829 return *this;
13830 }
13831
13834 json_pointer& operator/=(std::size_t array_idx)
13835 {
13836 return *this /= std::to_string(array_idx);
13837 }
13838
13842 const json_pointer& rhs)
13843 {
13844 return json_pointer(lhs) /= rhs;
13845 }
13846
13849 friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13850 {
13851 return json_pointer(lhs) /= std::move(token);
13852 }
13853
13856 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13857 {
13858 return json_pointer(lhs) /= array_idx;
13859 }
13860
13864 {
13865 if (empty())
13866 {
13867 return *this;
13868 }
13869
13870 json_pointer res = *this;
13871 res.pop_back();
13872 return res;
13873 }
13874
13878 {
13880 {
13881 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13882 }
13883
13884 reference_tokens.pop_back();
13885 }
13886
13889 const string_t& back() const
13890 {
13892 {
13893 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13894 }
13895
13896 return reference_tokens.back();
13897 }
13898
13901 void push_back(const string_t& token)
13902 {
13903 reference_tokens.push_back(token);
13904 }
13905
13908 void push_back(string_t&& token)
13909 {
13910 reference_tokens.push_back(std::move(token));
13911 }
13912
13915 bool empty() const noexcept
13916 {
13917 return reference_tokens.empty();
13918 }
13919
13920private:
13931 template<typename BasicJsonType>
13932 static typename BasicJsonType::size_type array_index(const string_t& s)
13933 {
13934 using size_type = typename BasicJsonType::size_type;
13935
13936 // error condition (cf. RFC 6901, Sect. 4)
13937 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13938 {
13939 JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13940 }
13941
13942 // error condition (cf. RFC 6901, Sect. 4)
13943 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13944 {
13945 JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13946 }
13947
13948 const char* p = s.c_str();
13949 char* p_end = nullptr;
13950 errno = 0; // strtoull doesn't reset errno
13951 const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13952 if (p == p_end // invalid input or empty string
13953 || errno == ERANGE // out of range
13954 || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13955 {
13956 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13957 }
13958
13959 // only triggered on special platforms (like 32bit), see also
13960 // https://github.com/nlohmann/json/pull/2203
13961 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13962 {
13963 JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13964 }
13965
13966 return static_cast<size_type>(res);
13967 }
13968
13970 json_pointer top() const
13971 {
13973 {
13974 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13975 }
13976
13977 json_pointer result = *this;
13978 result.reference_tokens = { reference_tokens[0] };
13979 return result;
13980 }
13981
13982private:
13991 template<typename BasicJsonType>
13992 BasicJsonType& get_and_create(BasicJsonType& j) const
13993 {
13994 auto* result = &j;
13995
13996 // in case no reference tokens exist, return a reference to the JSON value
13997 // j which will be overwritten by a primitive value
13998 for (const auto& reference_token : reference_tokens)
13999 {
14000 switch (result->type())
14001 {
14003 {
14004 if (reference_token == "0")
14005 {
14006 // start a new array if reference token is 0
14007 result = &result->operator[](0);
14008 }
14009 else
14010 {
14011 // start a new object otherwise
14012 result = &result->operator[](reference_token);
14013 }
14014 break;
14015 }
14016
14018 {
14019 // create an entry in the object
14020 result = &result->operator[](reference_token);
14021 break;
14022 }
14023
14025 {
14026 // create an entry in the array
14027 result = &result->operator[](array_index<BasicJsonType>(reference_token));
14028 break;
14029 }
14030
14031 /*
14032 The following code is only reached if there exists a reference
14033 token _and_ the current value is primitive. In this case, we have
14034 an error situation, because primitive values may only occur as
14035 single value; that is, with an empty list of reference tokens.
14036 */
14044 default:
14045 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14046 }
14047 }
14048
14049 return *result;
14050 }
14051
14071 template<typename BasicJsonType>
14072 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14073 {
14074 for (const auto& reference_token : reference_tokens)
14075 {
14076 // convert null values to arrays or objects before continuing
14077 if (ptr->is_null())
14078 {
14079 // check if reference token is a number
14080 const bool nums =
14081 std::all_of(reference_token.begin(), reference_token.end(),
14082 [](const unsigned char x)
14083 {
14084 return std::isdigit(x);
14085 });
14086
14087 // change value to array for numbers or "-" or to object otherwise
14088 *ptr = (nums || reference_token == "-")
14091 }
14092
14093 switch (ptr->type())
14094 {
14096 {
14097 // use unchecked object access
14098 ptr = &ptr->operator[](reference_token);
14099 break;
14100 }
14101
14103 {
14104 if (reference_token == "-")
14105 {
14106 // explicitly treat "-" as index beyond the end
14107 ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
14108 }
14109 else
14110 {
14111 // convert array index to number; unchecked access
14112 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14113 }
14114 break;
14115 }
14116
14125 default:
14126 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14127 }
14128 }
14129
14130 return *ptr;
14131 }
14132
14139 template<typename BasicJsonType>
14140 BasicJsonType& get_checked(BasicJsonType* ptr) const
14141 {
14142 for (const auto& reference_token : reference_tokens)
14143 {
14144 switch (ptr->type())
14145 {
14147 {
14148 // note: at performs range check
14149 ptr = &ptr->at(reference_token);
14150 break;
14151 }
14152
14154 {
14155 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14156 {
14157 // "-" always fails the range check
14159 "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14160 ") is out of range"), ptr));
14161 }
14162
14163 // note: at performs range check
14164 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14165 break;
14166 }
14167
14176 default:
14177 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14178 }
14179 }
14180
14181 return *ptr;
14182 }
14183
14197 template<typename BasicJsonType>
14198 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14199 {
14200 for (const auto& reference_token : reference_tokens)
14201 {
14202 switch (ptr->type())
14203 {
14205 {
14206 // use unchecked object access
14207 ptr = &ptr->operator[](reference_token);
14208 break;
14209 }
14210
14212 {
14213 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14214 {
14215 // "-" cannot be used for const access
14216 JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
14217 }
14218
14219 // use unchecked array access
14220 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14221 break;
14222 }
14223
14232 default:
14233 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14234 }
14235 }
14236
14237 return *ptr;
14238 }
14239
14246 template<typename BasicJsonType>
14247 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14248 {
14249 for (const auto& reference_token : reference_tokens)
14250 {
14251 switch (ptr->type())
14252 {
14254 {
14255 // note: at performs range check
14256 ptr = &ptr->at(reference_token);
14257 break;
14258 }
14259
14261 {
14262 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14263 {
14264 // "-" always fails the range check
14266 "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14267 ") is out of range"), ptr));
14268 }
14269
14270 // note: at performs range check
14271 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14272 break;
14273 }
14274
14283 default:
14284 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14285 }
14286 }
14287
14288 return *ptr;
14289 }
14290
14295 template<typename BasicJsonType>
14296 bool contains(const BasicJsonType* ptr) const
14297 {
14298 for (const auto& reference_token : reference_tokens)
14299 {
14300 switch (ptr->type())
14301 {
14303 {
14304 if (!ptr->contains(reference_token))
14305 {
14306 // we did not find the key in the object
14307 return false;
14308 }
14309
14310 ptr = &ptr->operator[](reference_token);
14311 break;
14312 }
14313
14315 {
14316 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14317 {
14318 // "-" always fails the range check
14319 return false;
14320 }
14321 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14322 {
14323 // invalid char
14324 return false;
14325 }
14326 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14327 {
14328 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14329 {
14330 // first char should be between '1' and '9'
14331 return false;
14332 }
14333 for (std::size_t i = 1; i < reference_token.size(); i++)
14334 {
14335 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14336 {
14337 // other char should be between '0' and '9'
14338 return false;
14339 }
14340 }
14341 }
14342
14343 const auto idx = array_index<BasicJsonType>(reference_token);
14344 if (idx >= ptr->size())
14345 {
14346 // index out of range
14347 return false;
14348 }
14349
14350 ptr = &ptr->operator[](idx);
14351 break;
14352 }
14353
14362 default:
14363 {
14364 // we do not expect primitive values if there is still a
14365 // reference token to process
14366 return false;
14367 }
14368 }
14369 }
14370
14371 // no reference token left means we found a primitive value
14372 return true;
14373 }
14374
14384 static std::vector<string_t> split(const string_t& reference_string)
14385 {
14386 std::vector<string_t> result;
14387
14388 // special case: empty reference string -> no reference tokens
14389 if (reference_string.empty())
14390 {
14391 return result;
14392 }
14393
14394 // check if nonempty reference string begins with slash
14395 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14396 {
14397 JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14398 }
14399
14400 // extract the reference tokens:
14401 // - slash: position of the last read slash (or end of string)
14402 // - start: position after the previous slash
14403 for (
14404 // search for the first slash after the first character
14405 std::size_t slash = reference_string.find_first_of('/', 1),
14406 // set the beginning of the first reference token
14407 start = 1;
14408 // we can stop if start == 0 (if slash == string_t::npos)
14409 start != 0;
14410 // set the beginning of the next reference token
14411 // (will eventually be 0 if slash == string_t::npos)
14412 start = (slash == string_t::npos) ? 0 : slash + 1,
14413 // find next slash
14414 slash = reference_string.find_first_of('/', start))
14415 {
14416 // use the text between the beginning of the reference token
14417 // (start) and the last slash (slash).
14418 auto reference_token = reference_string.substr(start, slash - start);
14419
14420 // check reference tokens are properly escaped
14421 for (std::size_t pos = reference_token.find_first_of('~');
14422 pos != string_t::npos;
14423 pos = reference_token.find_first_of('~', pos + 1))
14424 {
14425 JSON_ASSERT(reference_token[pos] == '~');
14426
14427 // ~ must be followed by 0 or 1
14428 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14429 (reference_token[pos + 1] != '0' &&
14430 reference_token[pos + 1] != '1')))
14431 {
14432 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14433 }
14434 }
14435
14436 // finally, store the reference token
14437 detail::unescape(reference_token);
14438 result.push_back(reference_token);
14439 }
14440
14441 return result;
14442 }
14443
14444private:
14452 template<typename BasicJsonType>
14453 static void flatten(const string_t& reference_string,
14454 const BasicJsonType& value,
14455 BasicJsonType& result)
14456 {
14457 switch (value.type())
14458 {
14460 {
14461 if (value.m_data.m_value.array->empty())
14462 {
14463 // flatten empty array as null
14464 result[reference_string] = nullptr;
14465 }
14466 else
14467 {
14468 // iterate array and use index as reference string
14469 for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
14470 {
14471 flatten(detail::concat(reference_string, '/', std::to_string(i)),
14472 value.m_data.m_value.array->operator[](i), result);
14473 }
14474 }
14475 break;
14476 }
14477
14479 {
14480 if (value.m_data.m_value.object->empty())
14481 {
14482 // flatten empty object as null
14483 result[reference_string] = nullptr;
14484 }
14485 else
14486 {
14487 // iterate object and use keys as reference string
14488 for (const auto& element : *value.m_data.m_value.object)
14489 {
14490 flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14491 }
14492 }
14493 break;
14494 }
14495
14504 default:
14505 {
14506 // add primitive value with its reference string
14507 result[reference_string] = value;
14508 break;
14509 }
14510 }
14511 }
14512
14523 template<typename BasicJsonType>
14524 static BasicJsonType
14525 unflatten(const BasicJsonType& value)
14526 {
14527 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14528 {
14529 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14530 }
14531
14532 BasicJsonType result;
14533
14534 // iterate the JSON object values
14535 for (const auto& element : *value.m_data.m_value.object)
14536 {
14537 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14538 {
14539 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14540 }
14541
14542 // assign value to reference pointed to by JSON pointer; Note that if
14543 // the JSON pointer is "" (i.e., points to the whole value), function
14544 // get_and_create returns a reference to result itself. An assignment
14545 // will then create a primitive value.
14546 json_pointer(element.first).get_and_create(result) = element.second;
14547 }
14548
14549 return result;
14550 }
14551
14552 // can't use conversion operator because of ambiguity
14553 json_pointer<string_t> convert() const&
14554 {
14556 result.reference_tokens = reference_tokens;
14557 return result;
14558 }
14559
14560 json_pointer<string_t> convert()&&
14561 {
14563 result.reference_tokens = std::move(reference_tokens);
14564 return result;
14565 }
14566
14567public:
14568#if JSON_HAS_THREE_WAY_COMPARISON
14571 template<typename RefStringTypeRhs>
14572 bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14573 {
14574 return reference_tokens == rhs.reference_tokens;
14575 }
14576
14579 JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
14580 bool operator==(const string_t& rhs) const
14581 {
14582 return *this == json_pointer(rhs);
14583 }
14584
14586 template<typename RefStringTypeRhs>
14587 std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
14588 {
14589 return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
14590 }
14591#else
14594 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14595 // NOLINTNEXTLINE(readability-redundant-declaration)
14596 friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14597 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14598
14601 template<typename RefStringTypeLhs, typename StringType>
14602 // NOLINTNEXTLINE(readability-redundant-declaration)
14603 friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14604 const StringType& rhs);
14605
14608 template<typename RefStringTypeRhs, typename StringType>
14609 // NOLINTNEXTLINE(readability-redundant-declaration)
14610 friend bool operator==(const StringType& lhs,
14612
14615 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14616 // NOLINTNEXTLINE(readability-redundant-declaration)
14617 friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14618 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14619
14622 template<typename RefStringTypeLhs, typename StringType>
14623 // NOLINTNEXTLINE(readability-redundant-declaration)
14624 friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14625 const StringType& rhs);
14626
14629 template<typename RefStringTypeRhs, typename StringType>
14630 // NOLINTNEXTLINE(readability-redundant-declaration)
14631 friend bool operator!=(const StringType& lhs,
14633
14635 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14636 // NOLINTNEXTLINE(readability-redundant-declaration)
14637 friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14638 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14639#endif
14640
14641private:
14643 std::vector<string_t> reference_tokens;
14644};
14645
14646#if !JSON_HAS_THREE_WAY_COMPARISON
14647// functions cannot be defined inside class due to ODR violations
14648template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14650 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14651{
14652 return lhs.reference_tokens == rhs.reference_tokens;
14653}
14654
14655template<typename RefStringTypeLhs,
14656 typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14658inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14659 const StringType& rhs)
14660{
14661 return lhs == json_pointer<RefStringTypeLhs>(rhs);
14662}
14663
14664template<typename RefStringTypeRhs,
14665 typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14667inline bool operator==(const StringType& lhs,
14668 const json_pointer<RefStringTypeRhs>& rhs)
14669{
14670 return json_pointer<RefStringTypeRhs>(lhs) == rhs;
14671}
14672
14673template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14675 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14676{
14677 return !(lhs == rhs);
14678}
14679
14680template<typename RefStringTypeLhs,
14681 typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14683inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14684 const StringType& rhs)
14685{
14686 return !(lhs == rhs);
14687}
14688
14689template<typename RefStringTypeRhs,
14690 typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14692inline bool operator!=(const StringType& lhs,
14693 const json_pointer<RefStringTypeRhs>& rhs)
14694{
14695 return !(lhs == rhs);
14696}
14697
14698template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14700 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14701{
14702 return lhs.reference_tokens < rhs.reference_tokens;
14703}
14704#endif
14705
14707
14708// #include <nlohmann/detail/json_ref.hpp>
14709// __ _____ _____ _____
14710// __| | __| | | | JSON for Modern C++
14711// | | |__ | | | | | | version 3.11.2
14712// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14713//
14714// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14715// SPDX-License-Identifier: MIT
14716
14717
14718
14719#include <initializer_list>
14720#include <utility>
14721
14722// #include <nlohmann/detail/abi_macros.hpp>
14723
14724// #include <nlohmann/detail/meta/type_traits.hpp>
14725
14726
14728namespace detail
14729{
14730
14731 template<typename BasicJsonType>
14733 {
14734 public:
14735 using value_type = BasicJsonType;
14736
14738 : owned_value(std::move(value))
14739 {}
14740
14742 : value_ref(&value)
14743 {}
14744
14745 json_ref(std::initializer_list<json_ref> init)
14746 : owned_value(init)
14747 {}
14748
14749 template <
14750 class... Args,
14751 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14752 json_ref(Args && ... args)
14753 : owned_value(std::forward<Args>(args)...)
14754 {}
14755
14756 // class should be movable only
14757 json_ref(json_ref&&) noexcept = default;
14758 json_ref(const json_ref&) = delete;
14759 json_ref& operator=(const json_ref&) = delete;
14760 json_ref& operator=(json_ref&&) = delete;
14761 ~json_ref() = default;
14762
14764 {
14765 if (value_ref == nullptr)
14766 {
14767 return std::move(owned_value);
14768 }
14769 return *value_ref;
14770 }
14771
14772 value_type const& operator*() const
14773 {
14774 return value_ref ? *value_ref : owned_value;
14775 }
14776
14777 value_type const* operator->() const
14778 {
14779 return &**this;
14780 }
14781
14782 private:
14783 mutable value_type owned_value = nullptr;
14784 value_type const* value_ref = nullptr;
14785 };
14786
14787} // namespace detail
14789
14790// #include <nlohmann/detail/macro_scope.hpp>
14791
14792// #include <nlohmann/detail/string_concat.hpp>
14793
14794// #include <nlohmann/detail/string_escape.hpp>
14795
14796// #include <nlohmann/detail/meta/cpp_future.hpp>
14797
14798// #include <nlohmann/detail/meta/type_traits.hpp>
14799
14800// #include <nlohmann/detail/output/binary_writer.hpp>
14801// __ _____ _____ _____
14802// __| | __| | | | JSON for Modern C++
14803// | | |__ | | | | | | version 3.11.2
14804// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14805//
14806// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14807// SPDX-License-Identifier: MIT
14808
14809
14810
14811#include <algorithm> // reverse
14812#include <array> // array
14813#include <map> // map
14814#include <cmath> // isnan, isinf
14815#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14816#include <cstring> // memcpy
14817#include <limits> // numeric_limits
14818#include <string> // string
14819#include <utility> // move
14820#include <vector> // vector
14821
14822// #include <nlohmann/detail/input/binary_reader.hpp>
14823
14824// #include <nlohmann/detail/macro_scope.hpp>
14825
14826// #include <nlohmann/detail/output/output_adapters.hpp>
14827// __ _____ _____ _____
14828// __| | __| | | | JSON for Modern C++
14829// | | |__ | | | | | | version 3.11.2
14830// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14831//
14832// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14833// SPDX-License-Identifier: MIT
14834
14835
14836
14837#include <algorithm> // copy
14838#include <cstddef> // size_t
14839#include <iterator> // back_inserter
14840#include <memory> // shared_ptr, make_shared
14841#include <string> // basic_string
14842#include <vector> // vector
14843
14844#ifndef JSON_NO_IO
14845#include <ios> // streamsize
14846#include <ostream> // basic_ostream
14847#endif // JSON_NO_IO
14848
14849// #include <nlohmann/detail/macro_scope.hpp>
14850
14851
14853namespace detail
14854{
14855
14857 template<typename CharType> struct output_adapter_protocol
14858 {
14859 virtual void write_character(CharType c) = 0;
14860 virtual void write_characters(const CharType* s, std::size_t length) = 0;
14861 virtual ~output_adapter_protocol() = default;
14862
14867 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14868 };
14869
14871 template<typename CharType>
14872 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14873
14875 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14877 {
14878 public:
14879 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14880 : v(vec)
14881 {}
14882
14883 void write_character(CharType c) override
14884 {
14885 v.push_back(c);
14886 }
14887
14889 void write_characters(const CharType* s, std::size_t length) override
14890 {
14891 v.insert(v.end(), s, s + length);
14892 }
14893
14894 private:
14895 std::vector<CharType, AllocatorType>& v;
14896 };
14897
14898#ifndef JSON_NO_IO
14900 template<typename CharType>
14902 {
14903 public:
14904 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14905 : stream(s)
14906 {}
14907
14908 void write_character(CharType c) override
14909 {
14910 stream.put(c);
14911 }
14912
14914 void write_characters(const CharType* s, std::size_t length) override
14915 {
14916 stream.write(s, static_cast<std::streamsize>(length));
14917 }
14918
14919 private:
14920 std::basic_ostream<CharType>& stream;
14921 };
14922#endif // JSON_NO_IO
14923
14925 template<typename CharType, typename StringType = std::basic_string<CharType>>
14927 {
14928 public:
14929 explicit output_string_adapter(StringType& s) noexcept
14930 : str(s)
14931 {}
14932
14933 void write_character(CharType c) override
14934 {
14935 str.push_back(c);
14936 }
14937
14939 void write_characters(const CharType* s, std::size_t length) override
14940 {
14941 str.append(s, length);
14942 }
14943
14944 private:
14945 StringType& str;
14946 };
14947
14948 template<typename CharType, typename StringType = std::basic_string<CharType>>
14950 {
14951 public:
14952 template<typename AllocatorType = std::allocator<CharType>>
14953 output_adapter(std::vector<CharType, AllocatorType>& vec)
14954 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14955
14956#ifndef JSON_NO_IO
14957 output_adapter(std::basic_ostream<CharType>& s)
14958 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14959#endif // JSON_NO_IO
14960
14961 output_adapter(StringType& s)
14962 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14963
14965 {
14966 return oa;
14967 }
14968
14969 private:
14970 output_adapter_t<CharType> oa = nullptr;
14971 };
14972
14973} // namespace detail
14975
14976// #include <nlohmann/detail/string_concat.hpp>
14977
14978
14980namespace detail
14981{
14982
14984 // binary writer //
14986
14990 template<typename BasicJsonType, typename CharType>
14992 {
14993 using string_t = typename BasicJsonType::string_t;
14994 using binary_t = typename BasicJsonType::binary_t;
14995 using number_float_t = typename BasicJsonType::number_float_t;
14996
14997 public:
15003 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
15004 {
15005 JSON_ASSERT(oa);
15006 }
15007
15012 void write_bson(const BasicJsonType& j)
15013 {
15014 switch (j.type())
15015 {
15016 case value_t::object:
15017 {
15018 write_bson_object(*j.m_data.m_value.object);
15019 break;
15020 }
15021
15022 case value_t::null:
15023 case value_t::array:
15024 case value_t::string:
15025 case value_t::boolean:
15026 case value_t::number_integer:
15027 case value_t::number_unsigned:
15028 case value_t::number_float:
15029 case value_t::binary:
15030 case value_t::discarded:
15031 default:
15032 {
15033 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
15034 }
15035 }
15036 }
15037
15041 void write_cbor(const BasicJsonType& j)
15042 {
15043 switch (j.type())
15044 {
15045 case value_t::null:
15046 {
15047 oa->write_character(to_char_type(0xF6));
15048 break;
15049 }
15050
15051 case value_t::boolean:
15052 {
15053 oa->write_character(j.m_data.m_value.boolean
15054 ? to_char_type(0xF5)
15055 : to_char_type(0xF4));
15056 break;
15057 }
15058
15059 case value_t::number_integer:
15060 {
15061 if (j.m_data.m_value.number_integer >= 0)
15062 {
15063 // CBOR does not differentiate between positive signed
15064 // integers and unsigned integers. Therefore, we used the
15065 // code from the value_t::number_unsigned case here.
15066 if (j.m_data.m_value.number_integer <= 0x17)
15067 {
15068 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15069 }
15070 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15071 {
15072 oa->write_character(to_char_type(0x18));
15073 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15074 }
15075 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15076 {
15077 oa->write_character(to_char_type(0x19));
15078 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15079 }
15080 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15081 {
15082 oa->write_character(to_char_type(0x1A));
15083 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15084 }
15085 else
15086 {
15087 oa->write_character(to_char_type(0x1B));
15088 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15089 }
15090 }
15091 else
15092 {
15093 // The conversions below encode the sign in the first
15094 // byte, and the value is converted to a positive number.
15095 const auto positive_number = -1 - j.m_data.m_value.number_integer;
15096 if (j.m_data.m_value.number_integer >= -24)
15097 {
15098 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15099 }
15100 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15101 {
15102 oa->write_character(to_char_type(0x38));
15103 write_number(static_cast<std::uint8_t>(positive_number));
15104 }
15105 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15106 {
15107 oa->write_character(to_char_type(0x39));
15108 write_number(static_cast<std::uint16_t>(positive_number));
15109 }
15110 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15111 {
15112 oa->write_character(to_char_type(0x3A));
15113 write_number(static_cast<std::uint32_t>(positive_number));
15114 }
15115 else
15116 {
15117 oa->write_character(to_char_type(0x3B));
15118 write_number(static_cast<std::uint64_t>(positive_number));
15119 }
15120 }
15121 break;
15122 }
15123
15124 case value_t::number_unsigned:
15125 {
15126 if (j.m_data.m_value.number_unsigned <= 0x17)
15127 {
15128 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15129 }
15130 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15131 {
15132 oa->write_character(to_char_type(0x18));
15133 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15134 }
15135 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15136 {
15137 oa->write_character(to_char_type(0x19));
15138 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
15139 }
15140 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15141 {
15142 oa->write_character(to_char_type(0x1A));
15143 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
15144 }
15145 else
15146 {
15147 oa->write_character(to_char_type(0x1B));
15148 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
15149 }
15150 break;
15151 }
15152
15153 case value_t::number_float:
15154 {
15155 if (std::isnan(j.m_data.m_value.number_float))
15156 {
15157 // NaN is 0xf97e00 in CBOR
15158 oa->write_character(to_char_type(0xF9));
15159 oa->write_character(to_char_type(0x7E));
15160 oa->write_character(to_char_type(0x00));
15161 }
15162 else if (std::isinf(j.m_data.m_value.number_float))
15163 {
15164 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15165 oa->write_character(to_char_type(0xf9));
15166 oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15167 oa->write_character(to_char_type(0x00));
15168 }
15169 else
15170 {
15171 write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
15172 }
15173 break;
15174 }
15175
15176 case value_t::string:
15177 {
15178 // step 1: write control byte and the string length
15179 const auto N = j.m_data.m_value.string->size();
15180 if (N <= 0x17)
15181 {
15182 write_number(static_cast<std::uint8_t>(0x60 + N));
15183 }
15184 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15185 {
15186 oa->write_character(to_char_type(0x78));
15187 write_number(static_cast<std::uint8_t>(N));
15188 }
15189 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15190 {
15191 oa->write_character(to_char_type(0x79));
15192 write_number(static_cast<std::uint16_t>(N));
15193 }
15194 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15195 {
15196 oa->write_character(to_char_type(0x7A));
15197 write_number(static_cast<std::uint32_t>(N));
15198 }
15199 // LCOV_EXCL_START
15200 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15201 {
15202 oa->write_character(to_char_type(0x7B));
15203 write_number(static_cast<std::uint64_t>(N));
15204 }
15205 // LCOV_EXCL_STOP
15206
15207 // step 2: write the string
15208 oa->write_characters(
15209 reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15210 j.m_data.m_value.string->size());
15211 break;
15212 }
15213
15214 case value_t::array:
15215 {
15216 // step 1: write control byte and the array size
15217 const auto N = j.m_data.m_value.array->size();
15218 if (N <= 0x17)
15219 {
15220 write_number(static_cast<std::uint8_t>(0x80 + N));
15221 }
15222 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15223 {
15224 oa->write_character(to_char_type(0x98));
15225 write_number(static_cast<std::uint8_t>(N));
15226 }
15227 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15228 {
15229 oa->write_character(to_char_type(0x99));
15230 write_number(static_cast<std::uint16_t>(N));
15231 }
15232 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15233 {
15234 oa->write_character(to_char_type(0x9A));
15235 write_number(static_cast<std::uint32_t>(N));
15236 }
15237 // LCOV_EXCL_START
15238 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15239 {
15240 oa->write_character(to_char_type(0x9B));
15241 write_number(static_cast<std::uint64_t>(N));
15242 }
15243 // LCOV_EXCL_STOP
15244
15245 // step 2: write each element
15246 for (const auto& el : *j.m_data.m_value.array)
15247 {
15248 write_cbor(el);
15249 }
15250 break;
15251 }
15252
15253 case value_t::binary:
15254 {
15255 if (j.m_data.m_value.binary->has_subtype())
15256 {
15257 if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15258 {
15259 write_number(static_cast<std::uint8_t>(0xd8));
15260 write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
15261 }
15262 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15263 {
15264 write_number(static_cast<std::uint8_t>(0xd9));
15265 write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
15266 }
15267 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15268 {
15269 write_number(static_cast<std::uint8_t>(0xda));
15270 write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
15271 }
15272 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15273 {
15274 write_number(static_cast<std::uint8_t>(0xdb));
15275 write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
15276 }
15277 }
15278
15279 // step 1: write control byte and the binary array size
15280 const auto N = j.m_data.m_value.binary->size();
15281 if (N <= 0x17)
15282 {
15283 write_number(static_cast<std::uint8_t>(0x40 + N));
15284 }
15285 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15286 {
15287 oa->write_character(to_char_type(0x58));
15288 write_number(static_cast<std::uint8_t>(N));
15289 }
15290 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15291 {
15292 oa->write_character(to_char_type(0x59));
15293 write_number(static_cast<std::uint16_t>(N));
15294 }
15295 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15296 {
15297 oa->write_character(to_char_type(0x5A));
15298 write_number(static_cast<std::uint32_t>(N));
15299 }
15300 // LCOV_EXCL_START
15301 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15302 {
15303 oa->write_character(to_char_type(0x5B));
15304 write_number(static_cast<std::uint64_t>(N));
15305 }
15306 // LCOV_EXCL_STOP
15307
15308 // step 2: write each element
15309 oa->write_characters(
15310 reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15311 N);
15312
15313 break;
15314 }
15315
15316 case value_t::object:
15317 {
15318 // step 1: write control byte and the object size
15319 const auto N = j.m_data.m_value.object->size();
15320 if (N <= 0x17)
15321 {
15322 write_number(static_cast<std::uint8_t>(0xA0 + N));
15323 }
15324 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15325 {
15326 oa->write_character(to_char_type(0xB8));
15327 write_number(static_cast<std::uint8_t>(N));
15328 }
15329 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15330 {
15331 oa->write_character(to_char_type(0xB9));
15332 write_number(static_cast<std::uint16_t>(N));
15333 }
15334 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15335 {
15336 oa->write_character(to_char_type(0xBA));
15337 write_number(static_cast<std::uint32_t>(N));
15338 }
15339 // LCOV_EXCL_START
15340 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15341 {
15342 oa->write_character(to_char_type(0xBB));
15343 write_number(static_cast<std::uint64_t>(N));
15344 }
15345 // LCOV_EXCL_STOP
15346
15347 // step 2: write each element
15348 for (const auto& el : *j.m_data.m_value.object)
15349 {
15350 write_cbor(el.first);
15351 write_cbor(el.second);
15352 }
15353 break;
15354 }
15355
15356 case value_t::discarded:
15357 default:
15358 break;
15359 }
15360 }
15361
15365 void write_msgpack(const BasicJsonType& j)
15366 {
15367 switch (j.type())
15368 {
15369 case value_t::null: // nil
15370 {
15371 oa->write_character(to_char_type(0xC0));
15372 break;
15373 }
15374
15375 case value_t::boolean: // true and false
15376 {
15377 oa->write_character(j.m_data.m_value.boolean
15378 ? to_char_type(0xC3)
15379 : to_char_type(0xC2));
15380 break;
15381 }
15382
15383 case value_t::number_integer:
15384 {
15385 if (j.m_data.m_value.number_integer >= 0)
15386 {
15387 // MessagePack does not differentiate between positive
15388 // signed integers and unsigned integers. Therefore, we used
15389 // the code from the value_t::number_unsigned case here.
15390 if (j.m_data.m_value.number_unsigned < 128)
15391 {
15392 // positive fixnum
15393 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15394 }
15395 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15396 {
15397 // uint 8
15398 oa->write_character(to_char_type(0xCC));
15399 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15400 }
15401 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15402 {
15403 // uint 16
15404 oa->write_character(to_char_type(0xCD));
15405 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15406 }
15407 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15408 {
15409 // uint 32
15410 oa->write_character(to_char_type(0xCE));
15411 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15412 }
15413 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15414 {
15415 // uint 64
15416 oa->write_character(to_char_type(0xCF));
15417 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15418 }
15419 }
15420 else
15421 {
15422 if (j.m_data.m_value.number_integer >= -32)
15423 {
15424 // negative fixnum
15425 write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15426 }
15427 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15428 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15429 {
15430 // int 8
15431 oa->write_character(to_char_type(0xD0));
15432 write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15433 }
15434 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15435 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15436 {
15437 // int 16
15438 oa->write_character(to_char_type(0xD1));
15439 write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
15440 }
15441 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15442 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15443 {
15444 // int 32
15445 oa->write_character(to_char_type(0xD2));
15446 write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
15447 }
15448 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15449 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15450 {
15451 // int 64
15452 oa->write_character(to_char_type(0xD3));
15453 write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
15454 }
15455 }
15456 break;
15457 }
15458
15459 case value_t::number_unsigned:
15460 {
15461 if (j.m_data.m_value.number_unsigned < 128)
15462 {
15463 // positive fixnum
15464 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15465 }
15466 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15467 {
15468 // uint 8
15469 oa->write_character(to_char_type(0xCC));
15470 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15471 }
15472 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15473 {
15474 // uint 16
15475 oa->write_character(to_char_type(0xCD));
15476 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15477 }
15478 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15479 {
15480 // uint 32
15481 oa->write_character(to_char_type(0xCE));
15482 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15483 }
15484 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15485 {
15486 // uint 64
15487 oa->write_character(to_char_type(0xCF));
15488 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15489 }
15490 break;
15491 }
15492
15493 case value_t::number_float:
15494 {
15495 write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
15496 break;
15497 }
15498
15499 case value_t::string:
15500 {
15501 // step 1: write control byte and the string length
15502 const auto N = j.m_data.m_value.string->size();
15503 if (N <= 31)
15504 {
15505 // fixstr
15506 write_number(static_cast<std::uint8_t>(0xA0 | N));
15507 }
15508 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15509 {
15510 // str 8
15511 oa->write_character(to_char_type(0xD9));
15512 write_number(static_cast<std::uint8_t>(N));
15513 }
15514 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15515 {
15516 // str 16
15517 oa->write_character(to_char_type(0xDA));
15518 write_number(static_cast<std::uint16_t>(N));
15519 }
15520 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15521 {
15522 // str 32
15523 oa->write_character(to_char_type(0xDB));
15524 write_number(static_cast<std::uint32_t>(N));
15525 }
15526
15527 // step 2: write the string
15528 oa->write_characters(
15529 reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15530 j.m_data.m_value.string->size());
15531 break;
15532 }
15533
15534 case value_t::array:
15535 {
15536 // step 1: write control byte and the array size
15537 const auto N = j.m_data.m_value.array->size();
15538 if (N <= 15)
15539 {
15540 // fixarray
15541 write_number(static_cast<std::uint8_t>(0x90 | N));
15542 }
15543 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15544 {
15545 // array 16
15546 oa->write_character(to_char_type(0xDC));
15547 write_number(static_cast<std::uint16_t>(N));
15548 }
15549 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15550 {
15551 // array 32
15552 oa->write_character(to_char_type(0xDD));
15553 write_number(static_cast<std::uint32_t>(N));
15554 }
15555
15556 // step 2: write each element
15557 for (const auto& el : *j.m_data.m_value.array)
15558 {
15559 write_msgpack(el);
15560 }
15561 break;
15562 }
15563
15564 case value_t::binary:
15565 {
15566 // step 0: determine if the binary type has a set subtype to
15567 // determine whether or not to use the ext or fixext types
15568 const bool use_ext = j.m_data.m_value.binary->has_subtype();
15569
15570 // step 1: write control byte and the byte string length
15571 const auto N = j.m_data.m_value.binary->size();
15572 if (N <= (std::numeric_limits<std::uint8_t>::max)())
15573 {
15574 std::uint8_t output_type{};
15575 bool fixed = true;
15576 if (use_ext)
15577 {
15578 switch (N)
15579 {
15580 case 1:
15581 output_type = 0xD4; // fixext 1
15582 break;
15583 case 2:
15584 output_type = 0xD5; // fixext 2
15585 break;
15586 case 4:
15587 output_type = 0xD6; // fixext 4
15588 break;
15589 case 8:
15590 output_type = 0xD7; // fixext 8
15591 break;
15592 case 16:
15593 output_type = 0xD8; // fixext 16
15594 break;
15595 default:
15596 output_type = 0xC7; // ext 8
15597 fixed = false;
15598 break;
15599 }
15600
15601 }
15602 else
15603 {
15604 output_type = 0xC4; // bin 8
15605 fixed = false;
15606 }
15607
15608 oa->write_character(to_char_type(output_type));
15609 if (!fixed)
15610 {
15611 write_number(static_cast<std::uint8_t>(N));
15612 }
15613 }
15614 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15615 {
15616 const std::uint8_t output_type = use_ext
15617 ? 0xC8 // ext 16
15618 : 0xC5; // bin 16
15619
15620 oa->write_character(to_char_type(output_type));
15621 write_number(static_cast<std::uint16_t>(N));
15622 }
15623 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15624 {
15625 const std::uint8_t output_type = use_ext
15626 ? 0xC9 // ext 32
15627 : 0xC6; // bin 32
15628
15629 oa->write_character(to_char_type(output_type));
15630 write_number(static_cast<std::uint32_t>(N));
15631 }
15632
15633 // step 1.5: if this is an ext type, write the subtype
15634 if (use_ext)
15635 {
15636 write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
15637 }
15638
15639 // step 2: write the byte string
15640 oa->write_characters(
15641 reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15642 N);
15643
15644 break;
15645 }
15646
15647 case value_t::object:
15648 {
15649 // step 1: write control byte and the object size
15650 const auto N = j.m_data.m_value.object->size();
15651 if (N <= 15)
15652 {
15653 // fixmap
15654 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15655 }
15656 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15657 {
15658 // map 16
15659 oa->write_character(to_char_type(0xDE));
15660 write_number(static_cast<std::uint16_t>(N));
15661 }
15662 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15663 {
15664 // map 32
15665 oa->write_character(to_char_type(0xDF));
15666 write_number(static_cast<std::uint32_t>(N));
15667 }
15668
15669 // step 2: write each element
15670 for (const auto& el : *j.m_data.m_value.object)
15671 {
15672 write_msgpack(el.first);
15673 write_msgpack(el.second);
15674 }
15675 break;
15676 }
15677
15678 case value_t::discarded:
15679 default:
15680 break;
15681 }
15682 }
15683
15691 void write_ubjson(const BasicJsonType& j, const bool use_count,
15692 const bool use_type, const bool add_prefix = true,
15693 const bool use_bjdata = false)
15694 {
15695 switch (j.type())
15696 {
15697 case value_t::null:
15698 {
15699 if (add_prefix)
15700 {
15701 oa->write_character(to_char_type('Z'));
15702 }
15703 break;
15704 }
15705
15706 case value_t::boolean:
15707 {
15708 if (add_prefix)
15709 {
15710 oa->write_character(j.m_data.m_value.boolean
15711 ? to_char_type('T')
15712 : to_char_type('F'));
15713 }
15714 break;
15715 }
15716
15717 case value_t::number_integer:
15718 {
15719 write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
15720 break;
15721 }
15722
15723 case value_t::number_unsigned:
15724 {
15725 write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
15726 break;
15727 }
15728
15729 case value_t::number_float:
15730 {
15731 write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
15732 break;
15733 }
15734
15735 case value_t::string:
15736 {
15737 if (add_prefix)
15738 {
15739 oa->write_character(to_char_type('S'));
15740 }
15741 write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
15742 oa->write_characters(
15743 reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15744 j.m_data.m_value.string->size());
15745 break;
15746 }
15747
15748 case value_t::array:
15749 {
15750 if (add_prefix)
15751 {
15752 oa->write_character(to_char_type('['));
15753 }
15754
15755 bool prefix_required = true;
15756 if (use_type && !j.m_data.m_value.array->empty())
15757 {
15758 JSON_ASSERT(use_count);
15759 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15760 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15761 [this, first_prefix, use_bjdata](const BasicJsonType& v)
15762 {
15763 return ubjson_prefix(v, use_bjdata) == first_prefix;
15764 });
15765
15766 std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
15767
15768 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15769 {
15770 prefix_required = false;
15771 oa->write_character(to_char_type('$'));
15772 oa->write_character(first_prefix);
15773 }
15774 }
15775
15776 if (use_count)
15777 {
15778 oa->write_character(to_char_type('#'));
15779 write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
15780 }
15781
15782 for (const auto& el : *j.m_data.m_value.array)
15783 {
15784 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15785 }
15786
15787 if (!use_count)
15788 {
15789 oa->write_character(to_char_type(']'));
15790 }
15791
15792 break;
15793 }
15794
15795 case value_t::binary:
15796 {
15797 if (add_prefix)
15798 {
15799 oa->write_character(to_char_type('['));
15800 }
15801
15802 if (use_type && !j.m_data.m_value.binary->empty())
15803 {
15804 JSON_ASSERT(use_count);
15805 oa->write_character(to_char_type('$'));
15806 oa->write_character('U');
15807 }
15808
15809 if (use_count)
15810 {
15811 oa->write_character(to_char_type('#'));
15812 write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
15813 }
15814
15815 if (use_type)
15816 {
15817 oa->write_characters(
15818 reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15819 j.m_data.m_value.binary->size());
15820 }
15821 else
15822 {
15823 for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
15824 {
15825 oa->write_character(to_char_type('U'));
15826 oa->write_character(j.m_data.m_value.binary->data()[i]);
15827 }
15828 }
15829
15830 if (!use_count)
15831 {
15832 oa->write_character(to_char_type(']'));
15833 }
15834
15835 break;
15836 }
15837
15838 case value_t::object:
15839 {
15840 if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
15841 {
15842 if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15843 {
15844 break;
15845 }
15846 }
15847
15848 if (add_prefix)
15849 {
15850 oa->write_character(to_char_type('{'));
15851 }
15852
15853 bool prefix_required = true;
15854 if (use_type && !j.m_data.m_value.object->empty())
15855 {
15856 JSON_ASSERT(use_count);
15857 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15858 const bool same_prefix = std::all_of(j.begin(), j.end(),
15859 [this, first_prefix, use_bjdata](const BasicJsonType& v)
15860 {
15861 return ubjson_prefix(v, use_bjdata) == first_prefix;
15862 });
15863
15864 std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
15865
15866 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15867 {
15868 prefix_required = false;
15869 oa->write_character(to_char_type('$'));
15870 oa->write_character(first_prefix);
15871 }
15872 }
15873
15874 if (use_count)
15875 {
15876 oa->write_character(to_char_type('#'));
15877 write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
15878 }
15879
15880 for (const auto& el : *j.m_data.m_value.object)
15881 {
15882 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15883 oa->write_characters(
15884 reinterpret_cast<const CharType*>(el.first.c_str()),
15885 el.first.size());
15886 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15887 }
15888
15889 if (!use_count)
15890 {
15891 oa->write_character(to_char_type('}'));
15892 }
15893
15894 break;
15895 }
15896
15897 case value_t::discarded:
15898 default:
15899 break;
15900 }
15901 }
15902
15903 private:
15905 // BSON //
15907
15912 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15913 {
15914 const auto it = name.find(static_cast<typename string_t::value_type>(0));
15915 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
15916 {
15917 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
15918 static_cast<void>(j);
15919 }
15920
15921 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
15922 }
15923
15927 void write_bson_entry_header(const string_t& name,
15928 const std::uint8_t element_type)
15929 {
15930 oa->write_character(to_char_type(element_type)); // boolean
15931 oa->write_characters(
15932 reinterpret_cast<const CharType*>(name.c_str()),
15933 name.size() + 1u);
15934 }
15935
15939 void write_bson_boolean(const string_t& name,
15940 const bool value)
15941 {
15942 write_bson_entry_header(name, 0x08);
15943 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15944 }
15945
15949 void write_bson_double(const string_t& name,
15950 const double value)
15951 {
15952 write_bson_entry_header(name, 0x01);
15953 write_number<double>(value, true);
15954 }
15955
15959 static std::size_t calc_bson_string_size(const string_t& value)
15960 {
15961 return sizeof(std::int32_t) + value.size() + 1ul;
15962 }
15963
15967 void write_bson_string(const string_t& name,
15968 const string_t& value)
15969 {
15970 write_bson_entry_header(name, 0x02);
15971
15972 write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15973 oa->write_characters(
15974 reinterpret_cast<const CharType*>(value.c_str()),
15975 value.size() + 1);
15976 }
15977
15981 void write_bson_null(const string_t& name)
15982 {
15983 write_bson_entry_header(name, 0x0A);
15984 }
15985
15989 static std::size_t calc_bson_integer_size(const std::int64_t value)
15990 {
15991 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15992 ? sizeof(std::int32_t)
15993 : sizeof(std::int64_t);
15994 }
15995
15999 void write_bson_integer(const string_t& name,
16000 const std::int64_t value)
16001 {
16002 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
16003 {
16004 write_bson_entry_header(name, 0x10); // int32
16005 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
16006 }
16007 else
16008 {
16009 write_bson_entry_header(name, 0x12); // int64
16010 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
16011 }
16012 }
16013
16017 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
16018 {
16019 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16020 ? sizeof(std::int32_t)
16021 : sizeof(std::int64_t);
16022 }
16023
16027 void write_bson_unsigned(const string_t& name,
16028 const BasicJsonType& j)
16029 {
16030 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16031 {
16032 write_bson_entry_header(name, 0x10 /* int32 */);
16033 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
16034 }
16035 else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16036 {
16037 write_bson_entry_header(name, 0x12 /* int64 */);
16038 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
16039 }
16040 else
16041 {
16042 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
16043 }
16044 }
16045
16049 void write_bson_object_entry(const string_t& name,
16050 const typename BasicJsonType::object_t& value)
16051 {
16052 write_bson_entry_header(name, 0x03); // object
16053 write_bson_object(value);
16054 }
16055
16059 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16060 {
16061 std::size_t array_index = 0ul;
16062
16063 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type& el)
16064 {
16065 return result + calc_bson_element_size(std::to_string(array_index++), el);
16066 });
16067
16068 return sizeof(std::int32_t) + embedded_document_size + 1ul;
16069 }
16070
16074 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16075 {
16076 return sizeof(std::int32_t) + value.size() + 1ul;
16077 }
16078
16082 void write_bson_array(const string_t& name,
16083 const typename BasicJsonType::array_t& value)
16084 {
16085 write_bson_entry_header(name, 0x04); // array
16086 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16087
16088 std::size_t array_index = 0ul;
16089
16090 for (const auto& el : value)
16091 {
16092 write_bson_element(std::to_string(array_index++), el);
16093 }
16094
16095 oa->write_character(to_char_type(0x00));
16096 }
16097
16101 void write_bson_binary(const string_t& name,
16102 const binary_t& value)
16103 {
16104 write_bson_entry_header(name, 0x05);
16105
16106 write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16107 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16108
16109 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16110 }
16111
16116 static std::size_t calc_bson_element_size(const string_t& name,
16117 const BasicJsonType& j)
16118 {
16119 const auto header_size = calc_bson_entry_header_size(name, j);
16120 switch (j.type())
16121 {
16122 case value_t::object:
16123 return header_size + calc_bson_object_size(*j.m_data.m_value.object);
16124
16125 case value_t::array:
16126 return header_size + calc_bson_array_size(*j.m_data.m_value.array);
16127
16128 case value_t::binary:
16129 return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
16130
16131 case value_t::boolean:
16132 return header_size + 1ul;
16133
16134 case value_t::number_float:
16135 return header_size + 8ul;
16136
16137 case value_t::number_integer:
16138 return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
16139
16140 case value_t::number_unsigned:
16141 return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
16142
16143 case value_t::string:
16144 return header_size + calc_bson_string_size(*j.m_data.m_value.string);
16145
16146 case value_t::null:
16147 return header_size + 0ul;
16148
16149 // LCOV_EXCL_START
16150 case value_t::discarded:
16151 default:
16152 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16153 return 0ul;
16154 // LCOV_EXCL_STOP
16155 }
16156 }
16157
16164 void write_bson_element(const string_t& name,
16165 const BasicJsonType& j)
16166 {
16167 switch (j.type())
16168 {
16169 case value_t::object:
16170 return write_bson_object_entry(name, *j.m_data.m_value.object);
16171
16172 case value_t::array:
16173 return write_bson_array(name, *j.m_data.m_value.array);
16174
16175 case value_t::binary:
16176 return write_bson_binary(name, *j.m_data.m_value.binary);
16177
16178 case value_t::boolean:
16179 return write_bson_boolean(name, j.m_data.m_value.boolean);
16180
16181 case value_t::number_float:
16182 return write_bson_double(name, j.m_data.m_value.number_float);
16183
16184 case value_t::number_integer:
16185 return write_bson_integer(name, j.m_data.m_value.number_integer);
16186
16187 case value_t::number_unsigned:
16188 return write_bson_unsigned(name, j);
16189
16190 case value_t::string:
16191 return write_bson_string(name, *j.m_data.m_value.string);
16192
16193 case value_t::null:
16194 return write_bson_null(name);
16195
16196 // LCOV_EXCL_START
16197 case value_t::discarded:
16198 default:
16199 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16200 return;
16201 // LCOV_EXCL_STOP
16202 }
16203 }
16204
16211 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
16212 {
16213 const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
16214 [](size_t result, const typename BasicJsonType::object_t::value_type& el)
16215 {
16216 return result += calc_bson_element_size(el.first, el.second);
16217 });
16218
16219 return sizeof(std::int32_t) + document_size + 1ul;
16220 }
16221
16226 void write_bson_object(const typename BasicJsonType::object_t& value)
16227 {
16228 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
16229
16230 for (const auto& el : value)
16231 {
16232 write_bson_element(el.first, el.second);
16233 }
16234
16235 oa->write_character(to_char_type(0x00));
16236 }
16237
16239 // CBOR //
16241
16242 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
16243 {
16244 return to_char_type(0xFA); // Single-Precision Float
16245 }
16246
16247 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16248 {
16249 return to_char_type(0xFB); // Double-Precision Float
16250 }
16251
16253 // MsgPack //
16255
16256 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16257 {
16258 return to_char_type(0xCA); // float 32
16259 }
16260
16261 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16262 {
16263 return to_char_type(0xCB); // float 64
16264 }
16265
16267 // UBJSON //
16269
16270 // UBJSON: write number (floating point)
16271 template<typename NumberType, typename std::enable_if<
16272 std::is_floating_point<NumberType>::value, int>::type = 0>
16273 void write_number_with_ubjson_prefix(const NumberType n,
16274 const bool add_prefix,
16275 const bool use_bjdata)
16276 {
16277 if (add_prefix)
16278 {
16279 oa->write_character(get_ubjson_float_prefix(n));
16280 }
16281 write_number(n, use_bjdata);
16282 }
16283
16284 // UBJSON: write number (unsigned integer)
16285 template<typename NumberType, typename std::enable_if<
16286 std::is_unsigned<NumberType>::value, int>::type = 0>
16287 void write_number_with_ubjson_prefix(const NumberType n,
16288 const bool add_prefix,
16289 const bool use_bjdata)
16290 {
16291 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16292 {
16293 if (add_prefix)
16294 {
16295 oa->write_character(to_char_type('i')); // int8
16296 }
16297 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16298 }
16299 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16300 {
16301 if (add_prefix)
16302 {
16303 oa->write_character(to_char_type('U')); // uint8
16304 }
16305 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16306 }
16307 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16308 {
16309 if (add_prefix)
16310 {
16311 oa->write_character(to_char_type('I')); // int16
16312 }
16313 write_number(static_cast<std::int16_t>(n), use_bjdata);
16314 }
16315 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16316 {
16317 if (add_prefix)
16318 {
16319 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16320 }
16321 write_number(static_cast<std::uint16_t>(n), use_bjdata);
16322 }
16323 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16324 {
16325 if (add_prefix)
16326 {
16327 oa->write_character(to_char_type('l')); // int32
16328 }
16329 write_number(static_cast<std::int32_t>(n), use_bjdata);
16330 }
16331 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16332 {
16333 if (add_prefix)
16334 {
16335 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16336 }
16337 write_number(static_cast<std::uint32_t>(n), use_bjdata);
16338 }
16339 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16340 {
16341 if (add_prefix)
16342 {
16343 oa->write_character(to_char_type('L')); // int64
16344 }
16345 write_number(static_cast<std::int64_t>(n), use_bjdata);
16346 }
16347 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16348 {
16349 if (add_prefix)
16350 {
16351 oa->write_character(to_char_type('M')); // uint64 - bjdata only
16352 }
16353 write_number(static_cast<std::uint64_t>(n), use_bjdata);
16354 }
16355 else
16356 {
16357 if (add_prefix)
16358 {
16359 oa->write_character(to_char_type('H')); // high-precision number
16360 }
16361
16362 const auto number = BasicJsonType(n).dump();
16363 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16364 for (std::size_t i = 0; i < number.size(); ++i)
16365 {
16366 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16367 }
16368 }
16369 }
16370
16371 // UBJSON: write number (signed integer)
16372 template < typename NumberType, typename std::enable_if <
16373 std::is_signed<NumberType>::value &&
16374 !std::is_floating_point<NumberType>::value, int >::type = 0 >
16375 void write_number_with_ubjson_prefix(const NumberType n,
16376 const bool add_prefix,
16377 const bool use_bjdata)
16378 {
16379 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16380 {
16381 if (add_prefix)
16382 {
16383 oa->write_character(to_char_type('i')); // int8
16384 }
16385 write_number(static_cast<std::int8_t>(n), use_bjdata);
16386 }
16387 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
16388 {
16389 if (add_prefix)
16390 {
16391 oa->write_character(to_char_type('U')); // uint8
16392 }
16393 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16394 }
16395 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16396 {
16397 if (add_prefix)
16398 {
16399 oa->write_character(to_char_type('I')); // int16
16400 }
16401 write_number(static_cast<std::int16_t>(n), use_bjdata);
16402 }
16403 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
16404 {
16405 if (add_prefix)
16406 {
16407 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16408 }
16409 write_number(static_cast<uint16_t>(n), use_bjdata);
16410 }
16411 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16412 {
16413 if (add_prefix)
16414 {
16415 oa->write_character(to_char_type('l')); // int32
16416 }
16417 write_number(static_cast<std::int32_t>(n), use_bjdata);
16418 }
16419 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
16420 {
16421 if (add_prefix)
16422 {
16423 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16424 }
16425 write_number(static_cast<uint32_t>(n), use_bjdata);
16426 }
16427 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16428 {
16429 if (add_prefix)
16430 {
16431 oa->write_character(to_char_type('L')); // int64
16432 }
16433 write_number(static_cast<std::int64_t>(n), use_bjdata);
16434 }
16435 // LCOV_EXCL_START
16436 else
16437 {
16438 if (add_prefix)
16439 {
16440 oa->write_character(to_char_type('H')); // high-precision number
16441 }
16442
16443 const auto number = BasicJsonType(n).dump();
16444 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16445 for (std::size_t i = 0; i < number.size(); ++i)
16446 {
16447 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16448 }
16449 }
16450 // LCOV_EXCL_STOP
16451 }
16452
16456 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16457 {
16458 switch (j.type())
16459 {
16460 case value_t::null:
16461 return 'Z';
16462
16463 case value_t::boolean:
16464 return j.m_data.m_value.boolean ? 'T' : 'F';
16465
16466 case value_t::number_integer:
16467 {
16468 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
16469 {
16470 return 'i';
16471 }
16472 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
16473 {
16474 return 'U';
16475 }
16476 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
16477 {
16478 return 'I';
16479 }
16480 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
16481 {
16482 return 'u';
16483 }
16484 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
16485 {
16486 return 'l';
16487 }
16488 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
16489 {
16490 return 'm';
16491 }
16492 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
16493 {
16494 return 'L';
16495 }
16496 // anything else is treated as high-precision number
16497 return 'H'; // LCOV_EXCL_LINE
16498 }
16499
16500 case value_t::number_unsigned:
16501 {
16502 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16503 {
16504 return 'i';
16505 }
16506 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16507 {
16508 return 'U';
16509 }
16510 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16511 {
16512 return 'I';
16513 }
16514 if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16515 {
16516 return 'u';
16517 }
16518 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16519 {
16520 return 'l';
16521 }
16522 if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16523 {
16524 return 'm';
16525 }
16526 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16527 {
16528 return 'L';
16529 }
16530 if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16531 {
16532 return 'M';
16533 }
16534 // anything else is treated as high-precision number
16535 return 'H'; // LCOV_EXCL_LINE
16536 }
16537
16538 case value_t::number_float:
16539 return get_ubjson_float_prefix(j.m_data.m_value.number_float);
16540
16541 case value_t::string:
16542 return 'S';
16543
16544 case value_t::array: // fallthrough
16545 case value_t::binary:
16546 return '[';
16547
16548 case value_t::object:
16549 return '{';
16550
16551 case value_t::discarded:
16552 default: // discarded values
16553 return 'N';
16554 }
16555 }
16556
16557 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16558 {
16559 return 'd'; // float 32
16560 }
16561
16562 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16563 {
16564 return 'D'; // float 64
16565 }
16566
16570 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16571 {
16572 std::map<string_t, CharType> bjdtype = { {"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16573 {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16574 };
16575
16576 string_t key = "_ArrayType_";
16577 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16578 if (it == bjdtype.end())
16579 {
16580 return true;
16581 }
16582 CharType dtype = it->second;
16583
16584 key = "_ArraySize_";
16585 std::size_t len = (value.at(key).empty() ? 0 : 1);
16586 for (const auto& el : value.at(key))
16587 {
16588 len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
16589 }
16590
16591 key = "_ArrayData_";
16592 if (value.at(key).size() != len)
16593 {
16594 return true;
16595 }
16596
16597 oa->write_character('[');
16598 oa->write_character('$');
16599 oa->write_character(dtype);
16600 oa->write_character('#');
16601
16602 key = "_ArraySize_";
16603 write_ubjson(value.at(key), use_count, use_type, true, true);
16604
16605 key = "_ArrayData_";
16606 if (dtype == 'U' || dtype == 'C')
16607 {
16608 for (const auto& el : value.at(key))
16609 {
16610 write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
16611 }
16612 }
16613 else if (dtype == 'i')
16614 {
16615 for (const auto& el : value.at(key))
16616 {
16617 write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
16618 }
16619 }
16620 else if (dtype == 'u')
16621 {
16622 for (const auto& el : value.at(key))
16623 {
16624 write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
16625 }
16626 }
16627 else if (dtype == 'I')
16628 {
16629 for (const auto& el : value.at(key))
16630 {
16631 write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
16632 }
16633 }
16634 else if (dtype == 'm')
16635 {
16636 for (const auto& el : value.at(key))
16637 {
16638 write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
16639 }
16640 }
16641 else if (dtype == 'l')
16642 {
16643 for (const auto& el : value.at(key))
16644 {
16645 write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
16646 }
16647 }
16648 else if (dtype == 'M')
16649 {
16650 for (const auto& el : value.at(key))
16651 {
16652 write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
16653 }
16654 }
16655 else if (dtype == 'L')
16656 {
16657 for (const auto& el : value.at(key))
16658 {
16659 write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
16660 }
16661 }
16662 else if (dtype == 'd')
16663 {
16664 for (const auto& el : value.at(key))
16665 {
16666 write_number(static_cast<float>(el.m_data.m_value.number_float), true);
16667 }
16668 }
16669 else if (dtype == 'D')
16670 {
16671 for (const auto& el : value.at(key))
16672 {
16673 write_number(static_cast<double>(el.m_data.m_value.number_float), true);
16674 }
16675 }
16676 return false;
16677 }
16678
16680 // Utility functions //
16682
16683 /*
16684 @brief write a number to output input
16685 @param[in] n number of type @a NumberType
16686 @param[in] OutputIsLittleEndian Set to true if output data is
16687 required to be little endian
16688 @tparam NumberType the type of the number
16689
16690 @note This function needs to respect the system's endianness, because bytes
16691 in CBOR, MessagePack, and UBJSON are stored in network order (big
16692 endian) and therefore need reordering on little endian systems.
16693 On the other hand, BSON and BJData use little endian and should reorder
16694 on big endian systems.
16695 */
16696 template<typename NumberType>
16697 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16698 {
16699 // step 1: write number to array of length NumberType
16700 std::array<CharType, sizeof(NumberType)> vec{};
16701 std::memcpy(vec.data(), &n, sizeof(NumberType));
16702
16703 // step 2: write array to output (with possible reordering)
16704 if (is_little_endian != OutputIsLittleEndian)
16705 {
16706 // reverse byte order prior to conversion if necessary
16707 std::reverse(vec.begin(), vec.end());
16708 }
16709
16710 oa->write_characters(vec.data(), sizeof(NumberType));
16711 }
16712
16713 void write_compact_float(const number_float_t n, detail::input_format_t format)
16714 {
16715#ifdef __GNUC__
16716#pragma GCC diagnostic push
16717#pragma GCC diagnostic ignored "-Wfloat-equal"
16718#endif
16719 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16720 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16721 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16722 {
16723 oa->write_character(format == detail::input_format_t::cbor
16724 ? get_cbor_float_prefix(static_cast<float>(n))
16725 : get_msgpack_float_prefix(static_cast<float>(n)));
16726 write_number(static_cast<float>(n));
16727 }
16728 else
16729 {
16730 oa->write_character(format == detail::input_format_t::cbor
16731 ? get_cbor_float_prefix(n)
16732 : get_msgpack_float_prefix(n));
16733 write_number(n);
16734 }
16735#ifdef __GNUC__
16736#pragma GCC diagnostic pop
16737#endif
16738 }
16739
16740 public:
16741 // The following to_char_type functions are implement the conversion
16742 // between uint8_t and CharType. In case CharType is not unsigned,
16743 // such a conversion is required to allow values greater than 128.
16744 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16745 template < typename C = CharType,
16746 enable_if_t < std::is_signed<C>::value&& std::is_signed<char>::value >* = nullptr >
16747 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16748 {
16749 return *reinterpret_cast<char*>(&x);
16750 }
16751
16752 template < typename C = CharType,
16753 enable_if_t < std::is_signed<C>::value&& std::is_unsigned<char>::value >* = nullptr >
16754 static CharType to_char_type(std::uint8_t x) noexcept
16755 {
16756 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16757 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16758 CharType result;
16759 std::memcpy(&result, &x, sizeof(x));
16760 return result;
16761 }
16762
16763 template<typename C = CharType,
16765 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16766 {
16767 return x;
16768 }
16769
16770 template < typename InputCharType, typename C = CharType,
16771 enable_if_t <
16772 std::is_signed<C>::value&&
16773 std::is_signed<char>::value&&
16774 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16775 >* = nullptr >
16776 static constexpr CharType to_char_type(InputCharType x) noexcept
16777 {
16778 return x;
16779 }
16780
16781 private:
16783 const bool is_little_endian = little_endianness();
16784
16786 output_adapter_t<CharType> oa = nullptr;
16787 };
16788
16789} // namespace detail
16791
16792// #include <nlohmann/detail/output/output_adapters.hpp>
16793
16794// #include <nlohmann/detail/output/serializer.hpp>
16795// __ _____ _____ _____
16796// __| | __| | | | JSON for Modern C++
16797// | | |__ | | | | | | version 3.11.2
16798// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16799//
16800// SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16801// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16802// SPDX-License-Identifier: MIT
16803
16804
16805
16806#include <algorithm> // reverse, remove, fill, find, none_of
16807#include <array> // array
16808#include <clocale> // localeconv, lconv
16809#include <cmath> // labs, isfinite, isnan, signbit
16810#include <cstddef> // size_t, ptrdiff_t
16811#include <cstdint> // uint8_t
16812#include <cstdio> // snprintf
16813#include <limits> // numeric_limits
16814#include <string> // string, char_traits
16815#include <iomanip> // setfill, setw
16816#include <type_traits> // is_same
16817#include <utility> // move
16818
16819// #include <nlohmann/detail/conversions/to_chars.hpp>
16820// __ _____ _____ _____
16821// __| | __| | | | JSON for Modern C++
16822// | | |__ | | | | | | version 3.11.2
16823// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16824//
16825// SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16826// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16827// SPDX-License-Identifier: MIT
16828
16829
16830
16831#include <array> // array
16832#include <cmath> // signbit, isfinite
16833#include <cstdint> // intN_t, uintN_t
16834#include <cstring> // memcpy, memmove
16835#include <limits> // numeric_limits
16836#include <type_traits> // conditional
16837
16838// #include <nlohmann/detail/macro_scope.hpp>
16839
16840
16842namespace detail
16843{
16844
16864 namespace dtoa_impl
16865 {
16866
16867 template<typename Target, typename Source>
16868 Target reinterpret_bits(const Source source)
16869 {
16870 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16871
16872 Target target;
16873 std::memcpy(&target, &source, sizeof(Source));
16874 return target;
16875 }
16876
16877 struct diyfp // f * 2^e
16878 {
16879 static constexpr int kPrecision = 64; // = q
16880
16881 std::uint64_t f = 0;
16882 int e = 0;
16883
16884 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16885
16890 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16891 {
16892 JSON_ASSERT(x.e == y.e);
16893 JSON_ASSERT(x.f >= y.f);
16894
16895 return { x.f - y.f, x.e };
16896 }
16897
16902 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16903 {
16904 static_assert(kPrecision == 64, "internal error");
16905
16906 // Computes:
16907 // f = round((x.f * y.f) / 2^q)
16908 // e = x.e + y.e + q
16909
16910 // Emulate the 64-bit * 64-bit multiplication:
16911 //
16912 // p = u * v
16913 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
16914 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
16915 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
16916 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
16917 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
16918 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
16919 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
16920 //
16921 // (Since Q might be larger than 2^32 - 1)
16922 //
16923 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
16924 //
16925 // (Q_hi + H does not overflow a 64-bit int)
16926 //
16927 // = p_lo + 2^64 p_hi
16928
16929 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
16930 const std::uint64_t u_hi = x.f >> 32u;
16931 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
16932 const std::uint64_t v_hi = y.f >> 32u;
16933
16934 const std::uint64_t p0 = u_lo * v_lo;
16935 const std::uint64_t p1 = u_lo * v_hi;
16936 const std::uint64_t p2 = u_hi * v_lo;
16937 const std::uint64_t p3 = u_hi * v_hi;
16938
16939 const std::uint64_t p0_hi = p0 >> 32u;
16940 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
16941 const std::uint64_t p1_hi = p1 >> 32u;
16942 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
16943 const std::uint64_t p2_hi = p2 >> 32u;
16944
16945 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
16946
16947 // The full product might now be computed as
16948 //
16949 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16950 // p_lo = p0_lo + (Q << 32)
16951 //
16952 // But in this particular case here, the full p_lo is not required.
16953 // Effectively we only need to add the highest bit in p_lo to p_hi (and
16954 // Q_hi + 1 does not overflow).
16955
16956 Q += std::uint64_t{ 1 } << (64u - 32u - 1u); // round, ties up
16957
16958 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16959
16960 return { h, x.e + y.e + 64 };
16961 }
16962
16967 static diyfp normalize(diyfp x) noexcept
16968 {
16969 JSON_ASSERT(x.f != 0);
16970
16971 while ((x.f >> 63u) == 0)
16972 {
16973 x.f <<= 1u;
16974 x.e--;
16975 }
16976
16977 return x;
16978 }
16979
16984 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16985 {
16986 const int delta = x.e - target_exponent;
16987
16988 JSON_ASSERT(delta >= 0);
16989 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16990
16991 return { x.f << delta, target_exponent };
16992 }
16993 };
16994
16996 {
17000 };
17001
17008 template<typename FloatType>
17010 {
17011 JSON_ASSERT(std::isfinite(value));
17012 JSON_ASSERT(value > 0);
17013
17014 // Convert the IEEE representation into a diyfp.
17015 //
17016 // If v is denormal:
17017 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17018 // If v is normalized:
17019 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17020
17021 static_assert(std::numeric_limits<FloatType>::is_iec559,
17022 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17023
17024 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17025 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17026 constexpr int kMinExp = 1 - kBias;
17027 constexpr std::uint64_t kHiddenBit = std::uint64_t{ 1 } << (kPrecision - 1); // = 2^(p-1)
17028
17029 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
17030
17031 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17032 const std::uint64_t E = bits >> (kPrecision - 1);
17033 const std::uint64_t F = bits & (kHiddenBit - 1);
17034
17035 const bool is_denormal = E == 0;
17036 const diyfp v = is_denormal
17037 ? diyfp(F, kMinExp)
17038 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17039
17040 // Compute the boundaries m- and m+ of the floating-point value
17041 // v = f * 2^e.
17042 //
17043 // Determine v- and v+, the floating-point predecessor and successor if v,
17044 // respectively.
17045 //
17046 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17047 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17048 //
17049 // v+ = v + 2^e
17050 //
17051 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17052 // between m- and m+ round to v, regardless of how the input rounding
17053 // algorithm breaks ties.
17054 //
17055 // ---+-------------+-------------+-------------+-------------+--- (A)
17056 // v- m- v m+ v+
17057 //
17058 // -----------------+------+------+-------------+-------------+--- (B)
17059 // v- m- v m+ v+
17060
17061 const bool lower_boundary_is_closer = F == 0 && E > 1;
17062 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17063 const diyfp m_minus = lower_boundary_is_closer
17064 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17065 : diyfp(2 * v.f - 1, v.e - 1); // (A)
17066
17067 // Determine the normalized w+ = m+.
17068 const diyfp w_plus = diyfp::normalize(m_plus);
17069
17070 // Determine w- = m- such that e_(w-) = e_(w+).
17071 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17072
17073 return { diyfp::normalize(v), w_minus, w_plus };
17074 }
17075
17076 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17077 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17078 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17079 //
17080 // alpha <= e = e_c + e_w + q <= gamma
17081 //
17082 // or
17083 //
17084 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17085 // <= f_c * f_w * 2^gamma
17086 //
17087 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17088 //
17089 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17090 //
17091 // or
17092 //
17093 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17094 //
17095 // The choice of (alpha,gamma) determines the size of the table and the form of
17096 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17097 // in practice:
17098 //
17099 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17100 // processed independently: An integral part p1, and a fractional part p2:
17101 //
17102 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17103 // = (f div 2^-e) + (f mod 2^-e) * 2^e
17104 // = p1 + p2 * 2^e
17105 //
17106 // The conversion of p1 into decimal form requires a series of divisions and
17107 // modulos by (a power of) 10. These operations are faster for 32-bit than for
17108 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17109 // achieved by choosing
17110 //
17111 // -e >= 32 or e <= -32 := gamma
17112 //
17113 // In order to convert the fractional part
17114 //
17115 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17116 //
17117 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17118 // d[-i] are extracted in order:
17119 //
17120 // (10 * p2) div 2^-e = d[-1]
17121 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17122 //
17123 // The multiplication by 10 must not overflow. It is sufficient to choose
17124 //
17125 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17126 //
17127 // Since p2 = f mod 2^-e < 2^-e,
17128 //
17129 // -e <= 60 or e >= -60 := alpha
17130
17131 constexpr int kAlpha = -60;
17132 constexpr int kGamma = -32;
17133
17134 struct cached_power // c = f * 2^e ~= 10^k
17135 {
17136 std::uint64_t f;
17137 int e;
17138 int k;
17139 };
17140
17149 {
17150 // Now
17151 //
17152 // alpha <= e_c + e + q <= gamma (1)
17153 // ==> f_c * 2^alpha <= c * 2^e * 2^q
17154 //
17155 // and since the c's are normalized, 2^(q-1) <= f_c,
17156 //
17157 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17158 // ==> 2^(alpha - e - 1) <= c
17159 //
17160 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17161 //
17162 // k = ceil( log_10( 2^(alpha - e - 1) ) )
17163 // = ceil( (alpha - e - 1) * log_10(2) )
17164 //
17165 // From the paper:
17166 // "In theory the result of the procedure could be wrong since c is rounded,
17167 // and the computation itself is approximated [...]. In practice, however,
17168 // this simple function is sufficient."
17169 //
17170 // For IEEE double precision floating-point numbers converted into
17171 // normalized diyfp's w = f * 2^e, with q = 64,
17172 //
17173 // e >= -1022 (min IEEE exponent)
17174 // -52 (p - 1)
17175 // -52 (p - 1, possibly normalize denormal IEEE numbers)
17176 // -11 (normalize the diyfp)
17177 // = -1137
17178 //
17179 // and
17180 //
17181 // e <= +1023 (max IEEE exponent)
17182 // -52 (p - 1)
17183 // -11 (normalize the diyfp)
17184 // = 960
17185 //
17186 // This binary exponent range [-1137,960] results in a decimal exponent
17187 // range [-307,324]. One does not need to store a cached power for each
17188 // k in this range. For each such k it suffices to find a cached power
17189 // such that the exponent of the product lies in [alpha,gamma].
17190 // This implies that the difference of the decimal exponents of adjacent
17191 // table entries must be less than or equal to
17192 //
17193 // floor( (gamma - alpha) * log_10(2) ) = 8.
17194 //
17195 // (A smaller distance gamma-alpha would require a larger table.)
17196
17197 // NB:
17198 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17199
17200 constexpr int kCachedPowersMinDecExp = -300;
17201 constexpr int kCachedPowersDecStep = 8;
17202
17203 static constexpr std::array<cached_power, 79> kCachedPowers =
17204 {
17205 {
17206 { 0xAB70FE17C79AC6CA, -1060, -300 },
17207 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
17208 { 0xBE5691EF416BD60C, -1007, -284 },
17209 { 0x8DD01FAD907FFC3C, -980, -276 },
17210 { 0xD3515C2831559A83, -954, -268 },
17211 { 0x9D71AC8FADA6C9B5, -927, -260 },
17212 { 0xEA9C227723EE8BCB, -901, -252 },
17213 { 0xAECC49914078536D, -874, -244 },
17214 { 0x823C12795DB6CE57, -847, -236 },
17215 { 0xC21094364DFB5637, -821, -228 },
17216 { 0x9096EA6F3848984F, -794, -220 },
17217 { 0xD77485CB25823AC7, -768, -212 },
17218 { 0xA086CFCD97BF97F4, -741, -204 },
17219 { 0xEF340A98172AACE5, -715, -196 },
17220 { 0xB23867FB2A35B28E, -688, -188 },
17221 { 0x84C8D4DFD2C63F3B, -661, -180 },
17222 { 0xC5DD44271AD3CDBA, -635, -172 },
17223 { 0x936B9FCEBB25C996, -608, -164 },
17224 { 0xDBAC6C247D62A584, -582, -156 },
17225 { 0xA3AB66580D5FDAF6, -555, -148 },
17226 { 0xF3E2F893DEC3F126, -529, -140 },
17227 { 0xB5B5ADA8AAFF80B8, -502, -132 },
17228 { 0x87625F056C7C4A8B, -475, -124 },
17229 { 0xC9BCFF6034C13053, -449, -116 },
17230 { 0x964E858C91BA2655, -422, -108 },
17231 { 0xDFF9772470297EBD, -396, -100 },
17232 { 0xA6DFBD9FB8E5B88F, -369, -92 },
17233 { 0xF8A95FCF88747D94, -343, -84 },
17234 { 0xB94470938FA89BCF, -316, -76 },
17235 { 0x8A08F0F8BF0F156B, -289, -68 },
17236 { 0xCDB02555653131B6, -263, -60 },
17237 { 0x993FE2C6D07B7FAC, -236, -52 },
17238 { 0xE45C10C42A2B3B06, -210, -44 },
17239 { 0xAA242499697392D3, -183, -36 },
17240 { 0xFD87B5F28300CA0E, -157, -28 },
17241 { 0xBCE5086492111AEB, -130, -20 },
17242 { 0x8CBCCC096F5088CC, -103, -12 },
17243 { 0xD1B71758E219652C, -77, -4 },
17244 { 0x9C40000000000000, -50, 4 },
17245 { 0xE8D4A51000000000, -24, 12 },
17246 { 0xAD78EBC5AC620000, 3, 20 },
17247 { 0x813F3978F8940984, 30, 28 },
17248 { 0xC097CE7BC90715B3, 56, 36 },
17249 { 0x8F7E32CE7BEA5C70, 83, 44 },
17250 { 0xD5D238A4ABE98068, 109, 52 },
17251 { 0x9F4F2726179A2245, 136, 60 },
17252 { 0xED63A231D4C4FB27, 162, 68 },
17253 { 0xB0DE65388CC8ADA8, 189, 76 },
17254 { 0x83C7088E1AAB65DB, 216, 84 },
17255 { 0xC45D1DF942711D9A, 242, 92 },
17256 { 0x924D692CA61BE758, 269, 100 },
17257 { 0xDA01EE641A708DEA, 295, 108 },
17258 { 0xA26DA3999AEF774A, 322, 116 },
17259 { 0xF209787BB47D6B85, 348, 124 },
17260 { 0xB454E4A179DD1877, 375, 132 },
17261 { 0x865B86925B9BC5C2, 402, 140 },
17262 { 0xC83553C5C8965D3D, 428, 148 },
17263 { 0x952AB45CFA97A0B3, 455, 156 },
17264 { 0xDE469FBD99A05FE3, 481, 164 },
17265 { 0xA59BC234DB398C25, 508, 172 },
17266 { 0xF6C69A72A3989F5C, 534, 180 },
17267 { 0xB7DCBF5354E9BECE, 561, 188 },
17268 { 0x88FCF317F22241E2, 588, 196 },
17269 { 0xCC20CE9BD35C78A5, 614, 204 },
17270 { 0x98165AF37B2153DF, 641, 212 },
17271 { 0xE2A0B5DC971F303A, 667, 220 },
17272 { 0xA8D9D1535CE3B396, 694, 228 },
17273 { 0xFB9B7CD9A4A7443C, 720, 236 },
17274 { 0xBB764C4CA7A44410, 747, 244 },
17275 { 0x8BAB8EEFB6409C1A, 774, 252 },
17276 { 0xD01FEF10A657842C, 800, 260 },
17277 { 0x9B10A4E5E9913129, 827, 268 },
17278 { 0xE7109BFBA19C0C9D, 853, 276 },
17279 { 0xAC2820D9623BF429, 880, 284 },
17280 { 0x80444B5E7AA7CF85, 907, 292 },
17281 { 0xBF21E44003ACDD2D, 933, 300 },
17282 { 0x8E679C2F5E44FF8F, 960, 308 },
17283 { 0xD433179D9C8CB841, 986, 316 },
17284 { 0x9E19DB92B4E31BA9, 1013, 324 },
17285 }
17286 };
17287
17288 // This computation gives exactly the same results for k as
17289 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17290 // for |e| <= 1500, but doesn't require floating-point operations.
17291 // NB: log_10(2) ~= 78913 / 2^18
17292 JSON_ASSERT(e >= -1500);
17293 JSON_ASSERT(e <= 1500);
17294 const int f = kAlpha - e - 1;
17295 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17296
17297 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17298 JSON_ASSERT(index >= 0);
17299 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17300
17301 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17302 JSON_ASSERT(kAlpha <= cached.e + e + 64);
17303 JSON_ASSERT(kGamma >= cached.e + e + 64);
17304
17305 return cached;
17306 }
17307
17312 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17313 {
17314 // LCOV_EXCL_START
17315 if (n >= 1000000000)
17316 {
17317 pow10 = 1000000000;
17318 return 10;
17319 }
17320 // LCOV_EXCL_STOP
17321 if (n >= 100000000)
17322 {
17323 pow10 = 100000000;
17324 return 9;
17325 }
17326 if (n >= 10000000)
17327 {
17328 pow10 = 10000000;
17329 return 8;
17330 }
17331 if (n >= 1000000)
17332 {
17333 pow10 = 1000000;
17334 return 7;
17335 }
17336 if (n >= 100000)
17337 {
17338 pow10 = 100000;
17339 return 6;
17340 }
17341 if (n >= 10000)
17342 {
17343 pow10 = 10000;
17344 return 5;
17345 }
17346 if (n >= 1000)
17347 {
17348 pow10 = 1000;
17349 return 4;
17350 }
17351 if (n >= 100)
17352 {
17353 pow10 = 100;
17354 return 3;
17355 }
17356 if (n >= 10)
17357 {
17358 pow10 = 10;
17359 return 2;
17360 }
17361
17362 pow10 = 1;
17363 return 1;
17364 }
17365
17366 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17367 std::uint64_t rest, std::uint64_t ten_k)
17368 {
17369 JSON_ASSERT(len >= 1);
17370 JSON_ASSERT(dist <= delta);
17371 JSON_ASSERT(rest <= delta);
17372 JSON_ASSERT(ten_k > 0);
17373
17374 // <--------------------------- delta ---->
17375 // <---- dist --------->
17376 // --------------[------------------+-------------------]--------------
17377 // M- w M+
17378 //
17379 // ten_k
17380 // <------>
17381 // <---- rest ---->
17382 // --------------[------------------+----+--------------]--------------
17383 // w V
17384 // = buf * 10^k
17385 //
17386 // ten_k represents a unit-in-the-last-place in the decimal representation
17387 // stored in buf.
17388 // Decrement buf by ten_k while this takes buf closer to w.
17389
17390 // The tests are written in this order to avoid overflow in unsigned
17391 // integer arithmetic.
17392
17393 while (rest < dist
17394 && delta - rest >= ten_k
17395 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17396 {
17397 JSON_ASSERT(buf[len - 1] != '0');
17398 buf[len - 1]--;
17399 rest += ten_k;
17400 }
17401 }
17402
17407 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17408 diyfp M_minus, diyfp w, diyfp M_plus)
17409 {
17410 static_assert(kAlpha >= -60, "internal error");
17411 static_assert(kGamma <= -32, "internal error");
17412
17413 // Generates the digits (and the exponent) of a decimal floating-point
17414 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17415 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17416 //
17417 // <--------------------------- delta ---->
17418 // <---- dist --------->
17419 // --------------[------------------+-------------------]--------------
17420 // M- w M+
17421 //
17422 // Grisu2 generates the digits of M+ from left to right and stops as soon as
17423 // V is in [M-,M+].
17424
17425 JSON_ASSERT(M_plus.e >= kAlpha);
17426 JSON_ASSERT(M_plus.e <= kGamma);
17427
17428 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17429 std::uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
17430
17431 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17432 //
17433 // M+ = f * 2^e
17434 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17435 // = ((p1 ) * 2^-e + (p2 )) * 2^e
17436 // = p1 + p2 * 2^e
17437
17438 const diyfp one(std::uint64_t{ 1 } << -M_plus.e, M_plus.e);
17439
17440 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
17441 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17442
17443 // 1)
17444 //
17445 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17446
17447 JSON_ASSERT(p1 > 0);
17448
17449 std::uint32_t pow10{};
17450 const int k = find_largest_pow10(p1, pow10);
17451
17452 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17453 //
17454 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17455 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17456 //
17457 // M+ = p1 + p2 * 2^e
17458 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17459 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17460 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17461 //
17462 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17463 //
17464 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17465 //
17466 // but stop as soon as
17467 //
17468 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17469
17470 int n = k;
17471 while (n > 0)
17472 {
17473 // Invariants:
17474 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17475 // pow10 = 10^(n-1) <= p1 < 10^n
17476 //
17477 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17478 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17479 //
17480 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17481 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17482 //
17483 JSON_ASSERT(d <= 9);
17484 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17485 //
17486 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17487 //
17488 p1 = r;
17489 n--;
17490 //
17491 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17492 // pow10 = 10^n
17493 //
17494
17495 // Now check if enough digits have been generated.
17496 // Compute
17497 //
17498 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17499 //
17500 // Note:
17501 // Since rest and delta share the same exponent e, it suffices to
17502 // compare the significands.
17503 const std::uint64_t rest = (std::uint64_t{ p1 } << -one.e) + p2;
17504 if (rest <= delta)
17505 {
17506 // V = buffer * 10^n, with M- <= V <= M+.
17507
17508 decimal_exponent += n;
17509
17510 // We may now just stop. But instead look if the buffer could be
17511 // decremented to bring V closer to w.
17512 //
17513 // pow10 = 10^n is now 1 ulp in the decimal representation V.
17514 // The rounding procedure works with diyfp's with an implicit
17515 // exponent of e.
17516 //
17517 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17518 //
17519 const std::uint64_t ten_n = std::uint64_t{ pow10 } << -one.e;
17520 grisu2_round(buffer, length, dist, delta, rest, ten_n);
17521
17522 return;
17523 }
17524
17525 pow10 /= 10;
17526 //
17527 // pow10 = 10^(n-1) <= p1 < 10^n
17528 // Invariants restored.
17529 }
17530
17531 // 2)
17532 //
17533 // The digits of the integral part have been generated:
17534 //
17535 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17536 // = buffer + p2 * 2^e
17537 //
17538 // Now generate the digits of the fractional part p2 * 2^e.
17539 //
17540 // Note:
17541 // No decimal point is generated: the exponent is adjusted instead.
17542 //
17543 // p2 actually represents the fraction
17544 //
17545 // p2 * 2^e
17546 // = p2 / 2^-e
17547 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17548 //
17549 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17550 //
17551 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17552 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17553 //
17554 // using
17555 //
17556 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17557 // = ( d) * 2^-e + ( r)
17558 //
17559 // or
17560 // 10^m * p2 * 2^e = d + r * 2^e
17561 //
17562 // i.e.
17563 //
17564 // M+ = buffer + p2 * 2^e
17565 // = buffer + 10^-m * (d + r * 2^e)
17566 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17567 //
17568 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17569
17570 JSON_ASSERT(p2 > delta);
17571
17572 int m = 0;
17573 for (;;)
17574 {
17575 // Invariant:
17576 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17577 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17578 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17579 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17580 //
17581 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17582 p2 *= 10;
17583 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17584 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17585 //
17586 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17587 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17588 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17589 //
17590 JSON_ASSERT(d <= 9);
17591 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17592 //
17593 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17594 //
17595 p2 = r;
17596 m++;
17597 //
17598 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17599 // Invariant restored.
17600
17601 // Check if enough digits have been generated.
17602 //
17603 // 10^-m * p2 * 2^e <= delta * 2^e
17604 // p2 * 2^e <= 10^m * delta * 2^e
17605 // p2 <= 10^m * delta
17606 delta *= 10;
17607 dist *= 10;
17608 if (p2 <= delta)
17609 {
17610 break;
17611 }
17612 }
17613
17614 // V = buffer * 10^-m, with M- <= V <= M+.
17615
17616 decimal_exponent -= m;
17617
17618 // 1 ulp in the decimal representation is now 10^-m.
17619 // Since delta and dist are now scaled by 10^m, we need to do the
17620 // same with ulp in order to keep the units in sync.
17621 //
17622 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17623 //
17624 const std::uint64_t ten_m = one.f;
17625 grisu2_round(buffer, length, dist, delta, p2, ten_m);
17626
17627 // By construction this algorithm generates the shortest possible decimal
17628 // number (Loitsch, Theorem 6.2) which rounds back to w.
17629 // For an input number of precision p, at least
17630 //
17631 // N = 1 + ceil(p * log_10(2))
17632 //
17633 // decimal digits are sufficient to identify all binary floating-point
17634 // numbers (Matula, "In-and-Out conversions").
17635 // This implies that the algorithm does not produce more than N decimal
17636 // digits.
17637 //
17638 // N = 17 for p = 53 (IEEE double precision)
17639 // N = 9 for p = 24 (IEEE single precision)
17640 }
17641
17648 inline void grisu2(char* buf, int& len, int& decimal_exponent,
17649 diyfp m_minus, diyfp v, diyfp m_plus)
17650 {
17651 JSON_ASSERT(m_plus.e == m_minus.e);
17652 JSON_ASSERT(m_plus.e == v.e);
17653
17654 // --------(-----------------------+-----------------------)-------- (A)
17655 // m- v m+
17656 //
17657 // --------------------(-----------+-----------------------)-------- (B)
17658 // m- v m+
17659 //
17660 // First scale v (and m- and m+) such that the exponent is in the range
17661 // [alpha, gamma].
17662
17663 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17664
17665 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17666
17667 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17668 const diyfp w = diyfp::mul(v, c_minus_k);
17669 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17670 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17671
17672 // ----(---+---)---------------(---+---)---------------(---+---)----
17673 // w- w w+
17674 // = c*m- = c*v = c*m+
17675 //
17676 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17677 // w+ are now off by a small amount.
17678 // In fact:
17679 //
17680 // w - v * 10^k < 1 ulp
17681 //
17682 // To account for this inaccuracy, add resp. subtract 1 ulp.
17683 //
17684 // --------+---[---------------(---+---)---------------]---+--------
17685 // w- M- w M+ w+
17686 //
17687 // Now any number in [M-, M+] (bounds included) will round to w when input,
17688 // regardless of how the input rounding algorithm breaks ties.
17689 //
17690 // And digit_gen generates the shortest possible such number in [M-, M+].
17691 // Note that this does not mean that Grisu2 always generates the shortest
17692 // possible number in the interval (m-, m+).
17693 const diyfp M_minus(w_minus.f + 1, w_minus.e);
17694 const diyfp M_plus(w_plus.f - 1, w_plus.e);
17695
17696 decimal_exponent = -cached.k; // = -(-k) = k
17697
17698 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17699 }
17700
17706 template<typename FloatType>
17708 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17709 {
17710 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17711 "internal error: not enough precision");
17712
17713 JSON_ASSERT(std::isfinite(value));
17714 JSON_ASSERT(value > 0);
17715
17716 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17717 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17718 // decimal representations are not exactly "short".
17719 //
17720 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17721 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17722 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17723 // does.
17724 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17725 // representation using the corresponding std::from_chars function recovers value exactly". That
17726 // indicates that single precision floating-point numbers should be recovered using
17727 // 'std::strtof'.
17728 //
17729 // NB: If the neighbors are computed for single-precision numbers, there is a single float
17730 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17731 // value is off by 1 ulp.
17732#if 0
17733 const boundaries w = compute_boundaries(static_cast<double>(value));
17734#else
17736#endif
17737
17738 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17739 }
17740
17748 inline char* append_exponent(char* buf, int e)
17749 {
17750 JSON_ASSERT(e > -1000);
17751 JSON_ASSERT(e < 1000);
17752
17753 if (e < 0)
17754 {
17755 e = -e;
17756 *buf++ = '-';
17757 }
17758 else
17759 {
17760 *buf++ = '+';
17761 }
17762
17763 auto k = static_cast<std::uint32_t>(e);
17764 if (k < 10)
17765 {
17766 // Always print at least two digits in the exponent.
17767 // This is for compatibility with printf("%g").
17768 *buf++ = '0';
17769 *buf++ = static_cast<char>('0' + k);
17770 }
17771 else if (k < 100)
17772 {
17773 *buf++ = static_cast<char>('0' + k / 10);
17774 k %= 10;
17775 *buf++ = static_cast<char>('0' + k);
17776 }
17777 else
17778 {
17779 *buf++ = static_cast<char>('0' + k / 100);
17780 k %= 100;
17781 *buf++ = static_cast<char>('0' + k / 10);
17782 k %= 10;
17783 *buf++ = static_cast<char>('0' + k);
17784 }
17785
17786 return buf;
17787 }
17788
17800 inline char* format_buffer(char* buf, int len, int decimal_exponent,
17801 int min_exp, int max_exp)
17802 {
17803 JSON_ASSERT(min_exp < 0);
17804 JSON_ASSERT(max_exp > 0);
17805
17806 const int k = len;
17807 const int n = len + decimal_exponent;
17808
17809 // v = buf * 10^(n-k)
17810 // k is the length of the buffer (number of decimal digits)
17811 // n is the position of the decimal point relative to the start of the buffer.
17812
17813 if (k <= n && n <= max_exp)
17814 {
17815 // digits[000]
17816 // len <= max_exp + 2
17817
17818 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17819 // Make it look like a floating-point number (#362, #378)
17820 buf[n + 0] = '.';
17821 buf[n + 1] = '0';
17822 return buf + (static_cast<size_t>(n) + 2);
17823 }
17824
17825 if (0 < n && n <= max_exp)
17826 {
17827 // dig.its
17828 // len <= max_digits10 + 1
17829
17830 JSON_ASSERT(k > n);
17831
17832 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17833 buf[n] = '.';
17834 return buf + (static_cast<size_t>(k) + 1U);
17835 }
17836
17837 if (min_exp < n && n <= 0)
17838 {
17839 // 0.[000]digits
17840 // len <= 2 + (-min_exp - 1) + max_digits10
17841
17842 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17843 buf[0] = '0';
17844 buf[1] = '.';
17845 std::memset(buf + 2, '0', static_cast<size_t>(-n));
17846 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17847 }
17848
17849 if (k == 1)
17850 {
17851 // dE+123
17852 // len <= 1 + 5
17853
17854 buf += 1;
17855 }
17856 else
17857 {
17858 // d.igitsE+123
17859 // len <= max_digits10 + 1 + 5
17860
17861 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17862 buf[1] = '.';
17863 buf += 1 + static_cast<size_t>(k);
17864 }
17865
17866 *buf++ = 'e';
17867 return append_exponent(buf, n - 1);
17868 }
17869
17870 } // namespace dtoa_impl
17871
17882 template<typename FloatType>
17885 char* to_chars(char* first, const char* last, FloatType value)
17886 {
17887 static_cast<void>(last); // maybe unused - fix warning
17888 JSON_ASSERT(std::isfinite(value));
17889
17890 // Use signbit(value) instead of (value < 0) since signbit works for -0.
17891 if (std::signbit(value))
17892 {
17893 value = -value;
17894 *first++ = '-';
17895 }
17896
17897#ifdef __GNUC__
17898#pragma GCC diagnostic push
17899#pragma GCC diagnostic ignored "-Wfloat-equal"
17900#endif
17901 if (value == 0) // +-0
17902 {
17903 *first++ = '0';
17904 // Make it look like a floating-point number (#362, #378)
17905 *first++ = '.';
17906 *first++ = '0';
17907 return first;
17908 }
17909#ifdef __GNUC__
17910#pragma GCC diagnostic pop
17911#endif
17912
17913 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
17914
17915 // Compute v = buffer * 10^decimal_exponent.
17916 // The decimal digits are stored in the buffer, which needs to be interpreted
17917 // as an unsigned decimal integer.
17918 // len is the length of the buffer, i.e. the number of decimal digits.
17919 int len = 0;
17920 int decimal_exponent = 0;
17921 dtoa_impl::grisu2(first, len, decimal_exponent, value);
17922
17923 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
17924
17925 // Format the buffer like printf("%.*g", prec, value)
17926 constexpr int kMinExp = -4;
17927 // Use digits10 here to increase compatibility with version 2.
17928 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
17929
17930 JSON_ASSERT(last - first >= kMaxExp + 2);
17931 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
17932 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
17933
17934 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
17935 }
17936
17937} // namespace detail
17939
17940// #include <nlohmann/detail/exceptions.hpp>
17941
17942// #include <nlohmann/detail/macro_scope.hpp>
17943
17944// #include <nlohmann/detail/meta/cpp_future.hpp>
17945
17946// #include <nlohmann/detail/output/binary_writer.hpp>
17947
17948// #include <nlohmann/detail/output/output_adapters.hpp>
17949
17950// #include <nlohmann/detail/string_concat.hpp>
17951
17952// #include <nlohmann/detail/value_t.hpp>
17953
17954
17956namespace detail
17957{
17958
17960 // serialization //
17962
17965 {
17966 strict,
17967 replace,
17968 ignore
17969 };
17970
17971 template<typename BasicJsonType>
17973 {
17974 using string_t = typename BasicJsonType::string_t;
17975 using number_float_t = typename BasicJsonType::number_float_t;
17976 using number_integer_t = typename BasicJsonType::number_integer_t;
17977 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17978 using binary_char_t = typename BasicJsonType::binary_t::value_type;
17979 static constexpr std::uint8_t UTF8_ACCEPT = 0;
17980 static constexpr std::uint8_t UTF8_REJECT = 1;
17981
17982 public:
17990 : o(std::move(s))
17991 , loc(std::localeconv())
17992 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
17993 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->decimal_point)))
17994 , indent_char(ichar)
17996 , error_handler(error_handler_)
17997 {}
17998
17999 // delete because of pointer members
18000 serializer(const serializer&) = delete;
18004 ~serializer() = default;
18005
18028 void dump(const BasicJsonType& val,
18029 const bool pretty_print,
18030 const bool ensure_ascii,
18031 const unsigned int indent_step,
18032 const unsigned int current_indent = 0)
18033 {
18034 switch (val.m_data.m_type)
18035 {
18036 case value_t::object:
18037 {
18038 if (val.m_data.m_value.object->empty())
18039 {
18040 o->write_characters("{}", 2);
18041 return;
18042 }
18043
18044 if (pretty_print)
18045 {
18046 o->write_characters("{\n", 2);
18047
18048 // variable to hold indentation for recursive calls
18049 const auto new_indent = current_indent + indent_step;
18050 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18051 {
18052 indent_string.resize(indent_string.size() * 2, ' ');
18053 }
18054
18055 // first n-1 elements
18056 auto i = val.m_data.m_value.object->cbegin();
18057 for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18058 {
18059 o->write_characters(indent_string.c_str(), new_indent);
18060 o->write_character('\"');
18061 dump_escaped(i->first, ensure_ascii);
18062 o->write_characters("\": ", 3);
18063 dump(i->second, true, ensure_ascii, indent_step, new_indent);
18064 o->write_characters(",\n", 2);
18065 }
18066
18067 // last element
18068 JSON_ASSERT(i != val.m_data.m_value.object->cend());
18069 JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18070 o->write_characters(indent_string.c_str(), new_indent);
18071 o->write_character('\"');
18072 dump_escaped(i->first, ensure_ascii);
18073 o->write_characters("\": ", 3);
18074 dump(i->second, true, ensure_ascii, indent_step, new_indent);
18075
18076 o->write_character('\n');
18077 o->write_characters(indent_string.c_str(), current_indent);
18078 o->write_character('}');
18079 }
18080 else
18081 {
18082 o->write_character('{');
18083
18084 // first n-1 elements
18085 auto i = val.m_data.m_value.object->cbegin();
18086 for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18087 {
18088 o->write_character('\"');
18089 dump_escaped(i->first, ensure_ascii);
18090 o->write_characters("\":", 2);
18091 dump(i->second, false, ensure_ascii, indent_step, current_indent);
18092 o->write_character(',');
18093 }
18094
18095 // last element
18096 JSON_ASSERT(i != val.m_data.m_value.object->cend());
18097 JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18098 o->write_character('\"');
18099 dump_escaped(i->first, ensure_ascii);
18100 o->write_characters("\":", 2);
18101 dump(i->second, false, ensure_ascii, indent_step, current_indent);
18102
18103 o->write_character('}');
18104 }
18105
18106 return;
18107 }
18108
18109 case value_t::array:
18110 {
18111 if (val.m_data.m_value.array->empty())
18112 {
18113 o->write_characters("[]", 2);
18114 return;
18115 }
18116
18117 if (pretty_print)
18118 {
18119 o->write_characters("[\n", 2);
18120
18121 // variable to hold indentation for recursive calls
18122 const auto new_indent = current_indent + indent_step;
18123 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18124 {
18125 indent_string.resize(indent_string.size() * 2, ' ');
18126 }
18127
18128 // first n-1 elements
18129 for (auto i = val.m_data.m_value.array->cbegin();
18130 i != val.m_data.m_value.array->cend() - 1; ++i)
18131 {
18132 o->write_characters(indent_string.c_str(), new_indent);
18133 dump(*i, true, ensure_ascii, indent_step, new_indent);
18134 o->write_characters(",\n", 2);
18135 }
18136
18137 // last element
18138 JSON_ASSERT(!val.m_data.m_value.array->empty());
18139 o->write_characters(indent_string.c_str(), new_indent);
18140 dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18141
18142 o->write_character('\n');
18143 o->write_characters(indent_string.c_str(), current_indent);
18144 o->write_character(']');
18145 }
18146 else
18147 {
18148 o->write_character('[');
18149
18150 // first n-1 elements
18151 for (auto i = val.m_data.m_value.array->cbegin();
18152 i != val.m_data.m_value.array->cend() - 1; ++i)
18153 {
18154 dump(*i, false, ensure_ascii, indent_step, current_indent);
18155 o->write_character(',');
18156 }
18157
18158 // last element
18159 JSON_ASSERT(!val.m_data.m_value.array->empty());
18160 dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18161
18162 o->write_character(']');
18163 }
18164
18165 return;
18166 }
18167
18168 case value_t::string:
18169 {
18170 o->write_character('\"');
18171 dump_escaped(*val.m_data.m_value.string, ensure_ascii);
18172 o->write_character('\"');
18173 return;
18174 }
18175
18176 case value_t::binary:
18177 {
18178 if (pretty_print)
18179 {
18180 o->write_characters("{\n", 2);
18181
18182 // variable to hold indentation for recursive calls
18183 const auto new_indent = current_indent + indent_step;
18184 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18185 {
18186 indent_string.resize(indent_string.size() * 2, ' ');
18187 }
18188
18189 o->write_characters(indent_string.c_str(), new_indent);
18190
18191 o->write_characters("\"bytes\": [", 10);
18192
18193 if (!val.m_data.m_value.binary->empty())
18194 {
18195 for (auto i = val.m_data.m_value.binary->cbegin();
18196 i != val.m_data.m_value.binary->cend() - 1; ++i)
18197 {
18198 dump_integer(*i);
18199 o->write_characters(", ", 2);
18200 }
18201 dump_integer(val.m_data.m_value.binary->back());
18202 }
18203
18204 o->write_characters("],\n", 3);
18205 o->write_characters(indent_string.c_str(), new_indent);
18206
18207 o->write_characters("\"subtype\": ", 11);
18208 if (val.m_data.m_value.binary->has_subtype())
18209 {
18210 dump_integer(val.m_data.m_value.binary->subtype());
18211 }
18212 else
18213 {
18214 o->write_characters("null", 4);
18215 }
18216 o->write_character('\n');
18217 o->write_characters(indent_string.c_str(), current_indent);
18218 o->write_character('}');
18219 }
18220 else
18221 {
18222 o->write_characters("{\"bytes\":[", 10);
18223
18224 if (!val.m_data.m_value.binary->empty())
18225 {
18226 for (auto i = val.m_data.m_value.binary->cbegin();
18227 i != val.m_data.m_value.binary->cend() - 1; ++i)
18228 {
18229 dump_integer(*i);
18230 o->write_character(',');
18231 }
18232 dump_integer(val.m_data.m_value.binary->back());
18233 }
18234
18235 o->write_characters("],\"subtype\":", 12);
18236 if (val.m_data.m_value.binary->has_subtype())
18237 {
18238 dump_integer(val.m_data.m_value.binary->subtype());
18239 o->write_character('}');
18240 }
18241 else
18242 {
18243 o->write_characters("null}", 5);
18244 }
18245 }
18246 return;
18247 }
18248
18249 case value_t::boolean:
18250 {
18251 if (val.m_data.m_value.boolean)
18252 {
18253 o->write_characters("true", 4);
18254 }
18255 else
18256 {
18257 o->write_characters("false", 5);
18258 }
18259 return;
18260 }
18261
18263 {
18264 dump_integer(val.m_data.m_value.number_integer);
18265 return;
18266 }
18267
18269 {
18270 dump_integer(val.m_data.m_value.number_unsigned);
18271 return;
18272 }
18273
18275 {
18276 dump_float(val.m_data.m_value.number_float);
18277 return;
18278 }
18279
18280 case value_t::discarded:
18281 {
18282 o->write_characters("<discarded>", 11);
18283 return;
18284 }
18285
18286 case value_t::null:
18287 {
18288 o->write_characters("null", 4);
18289 return;
18290 }
18291
18292 default: // LCOV_EXCL_LINE
18293 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18294 }
18295 }
18296
18312 void dump_escaped(const string_t& s, const bool ensure_ascii)
18313 {
18314 std::uint32_t codepoint{};
18315 std::uint8_t state = UTF8_ACCEPT;
18316 std::size_t bytes = 0; // number of bytes written to string_buffer
18317
18318 // number of bytes written at the point of the last valid byte
18320 std::size_t undumped_chars = 0;
18321
18322 for (std::size_t i = 0; i < s.size(); ++i)
18323 {
18324 const auto byte = static_cast<std::uint8_t>(s[i]);
18325
18326 switch (decode(state, codepoint, byte))
18327 {
18328 case UTF8_ACCEPT: // decode found a new code point
18329 {
18330 switch (codepoint)
18331 {
18332 case 0x08: // backspace
18333 {
18334 string_buffer[bytes++] = '\\';
18335 string_buffer[bytes++] = 'b';
18336 break;
18337 }
18338
18339 case 0x09: // horizontal tab
18340 {
18341 string_buffer[bytes++] = '\\';
18342 string_buffer[bytes++] = 't';
18343 break;
18344 }
18345
18346 case 0x0A: // newline
18347 {
18348 string_buffer[bytes++] = '\\';
18349 string_buffer[bytes++] = 'n';
18350 break;
18351 }
18352
18353 case 0x0C: // formfeed
18354 {
18355 string_buffer[bytes++] = '\\';
18356 string_buffer[bytes++] = 'f';
18357 break;
18358 }
18359
18360 case 0x0D: // carriage return
18361 {
18362 string_buffer[bytes++] = '\\';
18363 string_buffer[bytes++] = 'r';
18364 break;
18365 }
18366
18367 case 0x22: // quotation mark
18368 {
18369 string_buffer[bytes++] = '\\';
18370 string_buffer[bytes++] = '\"';
18371 break;
18372 }
18373
18374 case 0x5C: // reverse solidus
18375 {
18376 string_buffer[bytes++] = '\\';
18377 string_buffer[bytes++] = '\\';
18378 break;
18379 }
18380
18381 default:
18382 {
18383 // escape control characters (0x00..0x1F) or, if
18384 // ensure_ascii parameter is used, non-ASCII characters
18385 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18386 {
18387 if (codepoint <= 0xFFFF)
18388 {
18389 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18390 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18391 static_cast<std::uint16_t>(codepoint)));
18392 bytes += 6;
18393 }
18394 else
18395 {
18396 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18397 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18398 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18399 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18400 bytes += 12;
18401 }
18402 }
18403 else
18404 {
18405 // copy byte to buffer (all previous bytes
18406 // been copied have in default case above)
18407 string_buffer[bytes++] = s[i];
18408 }
18409 break;
18410 }
18411 }
18412
18413 // write buffer and reset index; there must be 13 bytes
18414 // left, as this is the maximal number of bytes to be
18415 // written ("\uxxxx\uxxxx\0") for one code point
18416 if (string_buffer.size() - bytes < 13)
18417 {
18418 o->write_characters(string_buffer.data(), bytes);
18419 bytes = 0;
18420 }
18421
18422 // remember the byte position of this accept
18424 undumped_chars = 0;
18425 break;
18426 }
18427
18428 case UTF8_REJECT: // decode found invalid UTF-8 byte
18429 {
18430 switch (error_handler)
18431 {
18433 {
18434 JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18435 }
18436
18439 {
18440 // in case we saw this character the first time, we
18441 // would like to read it again, because the byte
18442 // may be OK for itself, but just not OK for the
18443 // previous sequence
18444 if (undumped_chars > 0)
18445 {
18446 --i;
18447 }
18448
18449 // reset length buffer to the last accepted index;
18450 // thus removing/ignoring the invalid characters
18452
18454 {
18455 // add a replacement character
18456 if (ensure_ascii)
18457 {
18458 string_buffer[bytes++] = '\\';
18459 string_buffer[bytes++] = 'u';
18460 string_buffer[bytes++] = 'f';
18461 string_buffer[bytes++] = 'f';
18462 string_buffer[bytes++] = 'f';
18463 string_buffer[bytes++] = 'd';
18464 }
18465 else
18466 {
18470 }
18471
18472 // write buffer and reset index; there must be 13 bytes
18473 // left, as this is the maximal number of bytes to be
18474 // written ("\uxxxx\uxxxx\0") for one code point
18475 if (string_buffer.size() - bytes < 13)
18476 {
18477 o->write_characters(string_buffer.data(), bytes);
18478 bytes = 0;
18479 }
18480
18482 }
18483
18484 undumped_chars = 0;
18485
18486 // continue processing the string
18487 state = UTF8_ACCEPT;
18488 break;
18489 }
18490
18491 default: // LCOV_EXCL_LINE
18492 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18493 }
18494 break;
18495 }
18496
18497 default: // decode found yet incomplete multi-byte code point
18498 {
18499 if (!ensure_ascii)
18500 {
18501 // code point will not be escaped - copy byte to buffer
18502 string_buffer[bytes++] = s[i];
18503 }
18505 break;
18506 }
18507 }
18508 }
18509
18510 // we finished processing the string
18511 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
18512 {
18513 // write buffer
18514 if (bytes > 0)
18515 {
18516 o->write_characters(string_buffer.data(), bytes);
18517 }
18518 }
18519 else
18520 {
18521 // we finish reading, but do not accept: string was incomplete
18522 switch (error_handler)
18523 {
18525 {
18526 JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
18527 }
18528
18530 {
18531 // write all accepted bytes
18532 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18533 break;
18534 }
18535
18537 {
18538 // write all accepted bytes
18539 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18540 // add a replacement character
18541 if (ensure_ascii)
18542 {
18543 o->write_characters("\\ufffd", 6);
18544 }
18545 else
18546 {
18547 o->write_characters("\xEF\xBF\xBD", 3);
18548 }
18549 break;
18550 }
18551
18552 default: // LCOV_EXCL_LINE
18553 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18554 }
18555 }
18556 }
18557
18558 private:
18567 inline unsigned int count_digits(number_unsigned_t x) noexcept
18568 {
18569 unsigned int n_digits = 1;
18570 for (;;)
18571 {
18572 if (x < 10)
18573 {
18574 return n_digits;
18575 }
18576 if (x < 100)
18577 {
18578 return n_digits + 1;
18579 }
18580 if (x < 1000)
18581 {
18582 return n_digits + 2;
18583 }
18584 if (x < 10000)
18585 {
18586 return n_digits + 3;
18587 }
18588 x = x / 10000u;
18589 n_digits += 4;
18590 }
18591 }
18592
18598 static std::string hex_bytes(std::uint8_t byte)
18599 {
18600 std::string result = "FF";
18601 constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18602 result[0] = nibble_to_hex[byte / 16];
18603 result[1] = nibble_to_hex[byte % 16];
18604 return result;
18605 }
18606
18607 // templates to avoid warnings about useless casts
18608 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
18609 bool is_negative_number(NumberType x)
18610 {
18611 return x < 0;
18612 }
18613
18614 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
18615 bool is_negative_number(NumberType /*unused*/)
18616 {
18617 return false;
18618 }
18619
18629 template < typename NumberType, detail::enable_if_t <
18630 std::is_integral<NumberType>::value ||
18631 std::is_same<NumberType, number_unsigned_t>::value ||
18632 std::is_same<NumberType, number_integer_t>::value ||
18633 std::is_same<NumberType, binary_char_t>::value,
18634 int > = 0 >
18635 void dump_integer(NumberType x)
18636 {
18637 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18638 {
18639 {
18640 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18641 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18642 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18643 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18644 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18645 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18646 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18647 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18648 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18649 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18650 }
18651 };
18652
18653 // special case for "0"
18654 if (x == 0)
18655 {
18656 o->write_character('0');
18657 return;
18658 }
18659
18660 // use a pointer to fill the buffer
18661 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18662
18663 number_unsigned_t abs_value;
18664
18665 unsigned int n_chars{};
18666
18667 if (is_negative_number(x))
18668 {
18669 *buffer_ptr = '-';
18670 abs_value = remove_sign(static_cast<number_integer_t>(x));
18671
18672 // account one more byte for the minus sign
18673 n_chars = 1 + count_digits(abs_value);
18674 }
18675 else
18676 {
18677 abs_value = static_cast<number_unsigned_t>(x);
18678 n_chars = count_digits(abs_value);
18679 }
18680
18681 // spare 1 byte for '\0'
18682 JSON_ASSERT(n_chars < number_buffer.size() - 1);
18683
18684 // jump to the end to generate the string from backward,
18685 // so we later avoid reversing the result
18686 buffer_ptr += n_chars;
18687
18688 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18689 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18690 while (abs_value >= 100)
18691 {
18692 const auto digits_index = static_cast<unsigned>((abs_value % 100));
18693 abs_value /= 100;
18694 *(--buffer_ptr) = digits_to_99[digits_index][1];
18695 *(--buffer_ptr) = digits_to_99[digits_index][0];
18696 }
18697
18698 if (abs_value >= 10)
18699 {
18700 const auto digits_index = static_cast<unsigned>(abs_value);
18701 *(--buffer_ptr) = digits_to_99[digits_index][1];
18702 *(--buffer_ptr) = digits_to_99[digits_index][0];
18703 }
18704 else
18705 {
18706 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18707 }
18708
18709 o->write_characters(number_buffer.data(), n_chars);
18710 }
18711
18720 void dump_float(number_float_t x)
18721 {
18722 // NaN / inf
18723 if (!std::isfinite(x))
18724 {
18725 o->write_characters("null", 4);
18726 return;
18727 }
18728
18729 // If number_float_t is an IEEE-754 single or double precision number,
18730 // use the Grisu2 algorithm to produce short numbers which are
18731 // guaranteed to round-trip, using strtof and strtod, resp.
18732 //
18733 // NB: The test below works if <long double> == <double>.
18734 static constexpr bool is_ieee_single_or_double
18735 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
18736 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
18737
18738 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18739 }
18740
18741 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18742 {
18743 auto* begin = number_buffer.data();
18744 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18745
18746 o->write_characters(begin, static_cast<size_t>(end - begin));
18747 }
18748
18749 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18750 {
18751 // get number of digits for a float -> text -> float round-trip
18752 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18753
18754 // the actual conversion
18755 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18756 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18757
18758 // negative value indicates an error
18759 JSON_ASSERT(len > 0);
18760 // check if buffer was large enough
18761 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18762
18763 // erase thousands separator
18764 if (thousands_sep != '\0')
18765 {
18766 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18767 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18768 std::fill(end, number_buffer.end(), '\0');
18769 JSON_ASSERT((end - number_buffer.begin()) <= len);
18770 len = (end - number_buffer.begin());
18771 }
18772
18773 // convert decimal point to '.'
18774 if (decimal_point != '\0' && decimal_point != '.')
18775 {
18776 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18777 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18778 if (dec_pos != number_buffer.end())
18779 {
18780 *dec_pos = '.';
18781 }
18782 }
18783
18784 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18785
18786 // determine if we need to append ".0"
18787 const bool value_is_int_like =
18788 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18789 [](char c)
18790 {
18791 return c == '.' || c == 'e';
18792 });
18793
18794 if (value_is_int_like)
18795 {
18796 o->write_characters(".0", 2);
18797 }
18798 }
18799
18821 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18822 {
18823 static const std::array<std::uint8_t, 400> utf8d =
18824 {
18825 {
18826 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
18827 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
18828 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
18829 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
18830 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
18831 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
18832 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
18833 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18834 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18835 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18836 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
18837 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
18838 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
18839 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
18840 }
18841 };
18842
18843 JSON_ASSERT(byte < utf8d.size());
18844 const std::uint8_t type = utf8d[byte];
18845
18846 codep = (state != UTF8_ACCEPT)
18847 ? (byte & 0x3fu) | (codep << 6u)
18848 : (0xFFu >> type) & (byte);
18849
18850 const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18851 JSON_ASSERT(index < utf8d.size());
18852 state = utf8d[index];
18853 return state;
18854 }
18855
18856 /*
18857 * Overload to make the compiler happy while it is instantiating
18858 * dump_integer for number_unsigned_t.
18859 * Must never be called.
18860 */
18861 number_unsigned_t remove_sign(number_unsigned_t x)
18862 {
18863 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18864 return x; // LCOV_EXCL_LINE
18865 }
18866
18867 /*
18868 * Helper function for dump_integer
18869 *
18870 * This function takes a negative signed integer and returns its absolute
18871 * value as unsigned integer. The plus/minus shuffling is necessary as we can
18872 * not directly remove the sign of an arbitrary signed integer as the
18873 * absolute values of INT_MIN and INT_MAX are usually not the same. See
18874 * #1708 for details.
18875 */
18876 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18877 {
18878 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18879 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18880 }
18881
18882 private:
18884 output_adapter_t<char> o = nullptr;
18885
18887 std::array<char, 64> number_buffer{ {} };
18888
18890 const std::lconv* loc = nullptr;
18892 const char thousands_sep = '\0';
18894 const char decimal_point = '\0';
18895
18897 std::array<char, 512> string_buffer{ {} };
18898
18900 const char indent_char;
18903
18906 };
18907
18908} // namespace detail
18910
18911// #include <nlohmann/detail/value_t.hpp>
18912
18913// #include <nlohmann/json_fwd.hpp>
18914
18915// #include <nlohmann/ordered_map.hpp>
18916// __ _____ _____ _____
18917// __| | __| | | | JSON for Modern C++
18918// | | |__ | | | | | | version 3.11.2
18919// |_____|_____|_____|_|___| https://github.com/nlohmann/json
18920//
18921// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
18922// SPDX-License-Identifier: MIT
18923
18924
18925
18926#include <functional> // equal_to, less
18927#include <initializer_list> // initializer_list
18928#include <iterator> // input_iterator_tag, iterator_traits
18929#include <memory> // allocator
18930#include <stdexcept> // for out_of_range
18931#include <type_traits> // enable_if, is_convertible
18932#include <utility> // pair
18933#include <vector> // vector
18934
18935// #include <nlohmann/detail/macro_scope.hpp>
18936
18937// #include <nlohmann/detail/meta/type_traits.hpp>
18938
18939
18941
18944template <class Key, class T, class IgnoredLess = std::less<Key>,
18945 class Allocator = std::allocator<std::pair<const Key, T>>>
18946struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
18947{
18948 using key_type = Key;
18949 using mapped_type = T;
18950 using Container = std::vector<std::pair<const Key, T>, Allocator>;
18951 using iterator = typename Container::iterator;
18952 using const_iterator = typename Container::const_iterator;
18953 using size_type = typename Container::size_type;
18954 using value_type = typename Container::value_type;
18955#ifdef JSON_HAS_CPP_14
18956 using key_compare = std::equal_to<>;
18957#else
18958 using key_compare = std::equal_to<Key>;
18959#endif
18960
18961 // Explicit constructors instead of `using Container::Container`
18962 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18963 ordered_map() noexcept(noexcept(Container())) : Container{} {}
18964 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{ alloc } {}
18965 template <class It>
18966 ordered_map(It first, It last, const Allocator& alloc = Allocator())
18967 : Container{ first, last, alloc } {}
18968 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator())
18969 : Container{ init, alloc } {}
18970
18971 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18972 {
18973 for (auto it = this->begin(); it != this->end(); ++it)
18974 {
18975 if (m_compare(it->first, key))
18976 {
18977 return { it, false };
18978 }
18979 }
18980 Container::emplace_back(key, std::forward<T>(t));
18981 return { std::prev(this->end()), true };
18982 }
18983
18984 template<class KeyType, detail::enable_if_t<
18986 std::pair<iterator, bool> emplace(KeyType&& key, T&& t)
18987 {
18988 for (auto it = this->begin(); it != this->end(); ++it)
18989 {
18990 if (m_compare(it->first, key))
18991 {
18992 return { it, false };
18993 }
18994 }
18995 Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
18996 return { std::prev(this->end()), true };
18997 }
18998
18999 T& operator[](const key_type& key)
19000 {
19001 return emplace(key, T{}).first->second;
19002 }
19003
19004 template<class KeyType, detail::enable_if_t<
19006 T& operator[](KeyType&& key)
19007 {
19008 return emplace(std::forward<KeyType>(key), T{}).first->second;
19009 }
19010
19011 const T& operator[](const key_type& key) const
19012 {
19013 return at(key);
19014 }
19015
19016 template<class KeyType, detail::enable_if_t<
19018 const T& operator[](KeyType&& key) const
19019 {
19020 return at(std::forward<KeyType>(key));
19021 }
19022
19023 T& at(const key_type& key)
19024 {
19025 for (auto it = this->begin(); it != this->end(); ++it)
19026 {
19027 if (m_compare(it->first, key))
19028 {
19029 return it->second;
19030 }
19031 }
19032
19033 JSON_THROW(std::out_of_range("key not found"));
19034 }
19035
19036 template<class KeyType, detail::enable_if_t<
19038 T& at(KeyType&& key)
19039 {
19040 for (auto it = this->begin(); it != this->end(); ++it)
19041 {
19042 if (m_compare(it->first, key))
19043 {
19044 return it->second;
19045 }
19046 }
19047
19048 JSON_THROW(std::out_of_range("key not found"));
19049 }
19050
19051 const T& at(const key_type& key) const
19052 {
19053 for (auto it = this->begin(); it != this->end(); ++it)
19054 {
19055 if (m_compare(it->first, key))
19056 {
19057 return it->second;
19058 }
19059 }
19060
19061 JSON_THROW(std::out_of_range("key not found"));
19062 }
19063
19064 template<class KeyType, detail::enable_if_t<
19066 const T& at(KeyType&& key) const
19067 {
19068 for (auto it = this->begin(); it != this->end(); ++it)
19069 {
19070 if (m_compare(it->first, key))
19071 {
19072 return it->second;
19073 }
19074 }
19075
19076 JSON_THROW(std::out_of_range("key not found"));
19077 }
19078
19080 {
19081 for (auto it = this->begin(); it != this->end(); ++it)
19082 {
19083 if (m_compare(it->first, key))
19084 {
19085 // Since we cannot move const Keys, re-construct them in place
19086 for (auto next = it; ++next != this->end(); ++it)
19087 {
19088 it->~value_type(); // Destroy but keep allocation
19089 new (&*it) value_type{ std::move(*next) };
19090 }
19091 Container::pop_back();
19092 return 1;
19093 }
19094 }
19095 return 0;
19096 }
19097
19098 template<class KeyType, detail::enable_if_t<
19100 size_type erase(KeyType&& key)
19101 {
19102 for (auto it = this->begin(); it != this->end(); ++it)
19103 {
19104 if (m_compare(it->first, key))
19105 {
19106 // Since we cannot move const Keys, re-construct them in place
19107 for (auto next = it; ++next != this->end(); ++it)
19108 {
19109 it->~value_type(); // Destroy but keep allocation
19110 new (&*it) value_type{ std::move(*next) };
19111 }
19112 Container::pop_back();
19113 return 1;
19114 }
19115 }
19116 return 0;
19117 }
19118
19120 {
19121 return erase(pos, std::next(pos));
19122 }
19123
19125 {
19126 if (first == last)
19127 {
19128 return first;
19129 }
19130
19131 const auto elements_affected = std::distance(first, last);
19132 const auto offset = std::distance(Container::begin(), first);
19133
19134 // This is the start situation. We need to delete elements_affected
19135 // elements (3 in this example: e, f, g), and need to return an
19136 // iterator past the last deleted element (h in this example).
19137 // Note that offset is the distance from the start of the vector
19138 // to first. We will need this later.
19139
19140 // [ a, b, c, d, e, f, g, h, i, j ]
19141 // ^ ^
19142 // first last
19143
19144 // Since we cannot move const Keys, we re-construct them in place.
19145 // We start at first and re-construct (viz. copy) the elements from
19146 // the back of the vector. Example for first iteration:
19147
19148 // ,--------.
19149 // v | destroy e and re-construct with h
19150 // [ a, b, c, d, e, f, g, h, i, j ]
19151 // ^ ^
19152 // it it + elements_affected
19153
19154 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19155 {
19156 it->~value_type(); // destroy but keep allocation
19157 new (&*it) value_type{ std::move(*std::next(it, elements_affected)) }; // "move" next element to it
19158 }
19159
19160 // [ a, b, c, d, h, i, j, h, i, j ]
19161 // ^ ^
19162 // first last
19163
19164 // remove the unneeded elements at the end of the vector
19165 Container::resize(this->size() - static_cast<size_type>(elements_affected));
19166
19167 // [ a, b, c, d, h, i, j ]
19168 // ^ ^
19169 // first last
19170
19171 // first is now pointing past the last deleted element, but we cannot
19172 // use this iterator, because it may have been invalidated by the
19173 // resize call. Instead, we can return begin() + offset.
19174 return Container::begin() + offset;
19175 }
19176
19177 size_type count(const key_type& key) const
19178 {
19179 for (auto it = this->begin(); it != this->end(); ++it)
19180 {
19181 if (m_compare(it->first, key))
19182 {
19183 return 1;
19184 }
19185 }
19186 return 0;
19187 }
19188
19189 template<class KeyType, detail::enable_if_t<
19191 size_type count(KeyType&& key) const
19192 {
19193 for (auto it = this->begin(); it != this->end(); ++it)
19194 {
19195 if (m_compare(it->first, key))
19196 {
19197 return 1;
19198 }
19199 }
19200 return 0;
19201 }
19202
19204 {
19205 for (auto it = this->begin(); it != this->end(); ++it)
19206 {
19207 if (m_compare(it->first, key))
19208 {
19209 return it;
19210 }
19211 }
19212 return Container::end();
19213 }
19214
19215 template<class KeyType, detail::enable_if_t<
19217 iterator find(KeyType&& key)
19218 {
19219 for (auto it = this->begin(); it != this->end(); ++it)
19220 {
19221 if (m_compare(it->first, key))
19222 {
19223 return it;
19224 }
19225 }
19226 return Container::end();
19227 }
19228
19229 const_iterator find(const key_type& key) const
19230 {
19231 for (auto it = this->begin(); it != this->end(); ++it)
19232 {
19233 if (m_compare(it->first, key))
19234 {
19235 return it;
19236 }
19237 }
19238 return Container::end();
19239 }
19240
19241 std::pair<iterator, bool> insert(value_type&& value)
19242 {
19243 return emplace(value.first, std::move(value.second));
19244 }
19245
19246 std::pair<iterator, bool> insert(const value_type& value)
19247 {
19248 for (auto it = this->begin(); it != this->end(); ++it)
19249 {
19250 if (m_compare(it->first, value.first))
19251 {
19252 return { it, false };
19253 }
19254 }
19255 Container::push_back(value);
19256 return { --this->end(), true };
19257 }
19258
19259 template<typename InputIt>
19260 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19261 std::input_iterator_tag>::value>::type;
19262
19263 template<typename InputIt, typename = require_input_iter<InputIt>>
19264 void insert(InputIt first, InputIt last)
19265 {
19266 for (auto it = first; it != last; ++it)
19267 {
19268 insert(*it);
19269 }
19270 }
19271
19272private:
19274};
19275
19277
19278
19279#if defined(JSON_HAS_CPP_17)
19280#include <any>
19281#include <string_view>
19282#endif
19283
19290
19310class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19311 : public ::nlohmann::detail::json_base_class<CustomBaseClass>
19312{
19313private:
19314 template<detail::value_t> friend struct detail::external_constructor;
19315
19316 template<typename>
19317 friend class ::nlohmann::json_pointer;
19318 // can be restored when json_pointer backwards compatibility is removed
19319 // friend ::nlohmann::json_pointer<StringType>;
19320
19321 template<typename BasicJsonType, typename InputType>
19322 friend class ::nlohmann::detail::parser;
19323 friend ::nlohmann::detail::serializer<basic_json>;
19324 template<typename BasicJsonType>
19325 friend class ::nlohmann::detail::iter_impl;
19326 template<typename BasicJsonType, typename CharType>
19327 friend class ::nlohmann::detail::binary_writer;
19328 template<typename BasicJsonType, typename InputType, typename SAX>
19329 friend class ::nlohmann::detail::binary_reader;
19330 template<typename BasicJsonType>
19331 friend class ::nlohmann::detail::json_sax_dom_parser;
19332 template<typename BasicJsonType>
19333 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19334 friend class ::nlohmann::detail::exception;
19335
19337 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
19338 using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
19339
19341 // convenience aliases for types residing in namespace detail;
19342 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19343
19344 template<typename InputAdapterType>
19345 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19346 InputAdapterType adapter,
19348 const bool allow_exceptions = true,
19349 const bool ignore_comments = false
19350 )
19351 {
19352 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19353 std::move(cb), allow_exceptions, ignore_comments);
19354 }
19355
19356private:
19357 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19358 template<typename BasicJsonType>
19359 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19360 template<typename BasicJsonType>
19361 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19362 template<typename Iterator>
19363 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19364 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19365
19366 template<typename CharType>
19367 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19368
19369 template<typename InputType>
19370 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19371 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19372
19374 using serializer = ::nlohmann::detail::serializer<basic_json>;
19375
19376public:
19379 using json_pointer = ::nlohmann::json_pointer<StringType>;
19380 template<typename T, typename SFINAE>
19381 using json_serializer = JSONSerializer<T, SFINAE>;
19387 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19388
19392
19394 // exceptions //
19396
19400
19407
19409
19410
19412 // container types //
19414
19419
19422
19427
19429 using difference_type = std::ptrdiff_t;
19431 using size_type = std::size_t;
19432
19434 using allocator_type = AllocatorType<basic_json>;
19435
19437 using pointer = typename std::allocator_traits<allocator_type>::pointer;
19439 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19440
19442 using iterator = iter_impl<basic_json>;
19444 using const_iterator = iter_impl<const basic_json>;
19446 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
19448 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
19449
19451
19452
19456 {
19457 return allocator_type();
19458 }
19459
19464 {
19465 basic_json result;
19466
19467 result["copyright"] = "(C) 2013-2022 Niels Lohmann";
19468 result["name"] = "JSON for Modern C++";
19469 result["url"] = "https://github.com/nlohmann/json";
19470 result["version"]["string"] =
19471 detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
19472 std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
19473 std::to_string(NLOHMANN_JSON_VERSION_PATCH));
19474 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19475 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19476 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19477
19478#ifdef _WIN32
19479 result["platform"] = "win32";
19480#elif defined __linux__
19481 result["platform"] = "linux";
19482#elif defined __APPLE__
19483 result["platform"] = "apple";
19484#elif defined __unix__
19485 result["platform"] = "unix";
19486#else
19487 result["platform"] = "unknown";
19488#endif
19489
19490#if defined(__ICC) || defined(__INTEL_COMPILER)
19491 result["compiler"] = { {"family", "icc"}, {"version", __INTEL_COMPILER} };
19492#elif defined(__clang__)
19493 result["compiler"] = { {"family", "clang"}, {"version", __clang_version__} };
19494#elif defined(__GNUC__) || defined(__GNUG__)
19495 result["compiler"] = { {"family", "gcc"}, {"version", detail::concat(
19496 std::to_string(__GNUC__), '.',
19497 std::to_string(__GNUC_MINOR__), '.',
19498 std::to_string(__GNUC_PATCHLEVEL__))
19499 }
19500 };
19501#elif defined(__HP_cc) || defined(__HP_aCC)
19502 result["compiler"] = "hp"
19503#elif defined(__IBMCPP__)
19504 result["compiler"] = { {"family", "ilecpp"}, {"version", __IBMCPP__} };
19505#elif defined(_MSC_VER)
19506 result["compiler"] = { {"family", "msvc"}, {"version", _MSC_VER} };
19507#elif defined(__PGI)
19508 result["compiler"] = { {"family", "pgcpp"}, {"version", __PGI} };
19509#elif defined(__SUNPRO_CC)
19510 result["compiler"] = { {"family", "sunpro"}, {"version", __SUNPRO_CC} };
19511#else
19512 result["compiler"] = { {"family", "unknown"}, {"version", "unknown"} };
19513#endif
19514
19515
19516#if defined(_MSVC_LANG)
19517 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19518#elif defined(__cplusplus)
19519 result["compiler"]["c++"] = std::to_string(__cplusplus);
19520#else
19521 result["compiler"]["c++"] = "unknown";
19522#endif
19523 return result;
19524 }
19525
19526
19528 // JSON value data types //
19530
19535
19540#if defined(JSON_HAS_CPP_14)
19541 // use of transparent comparator avoids unnecessary repeated construction of temporaries
19542 // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19543 using default_object_comparator_t = std::less<>;
19544#else
19545 using default_object_comparator_t = std::less<StringType>;
19546#endif
19547
19550 using object_t = ObjectType<StringType,
19551 basic_json,
19553 AllocatorType<std::pair<const StringType,
19554 basic_json>>>;
19555
19558 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19559
19562 using string_t = StringType;
19563
19566 using boolean_t = BooleanType;
19567
19570 using number_integer_t = NumberIntegerType;
19571
19574 using number_unsigned_t = NumberUnsignedType;
19575
19578 using number_float_t = NumberFloatType;
19579
19582 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19583
19587
19589
19590private:
19591
19593 template<typename T, typename... Args>
19595 static T* create(Args&& ... args)
19596 {
19597 AllocatorType<T> alloc;
19598 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19599
19600 auto deleter = [&](T* obj)
19601 {
19602 AllocatorTraits::deallocate(alloc, obj, 1);
19603 };
19604 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19605 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19606 JSON_ASSERT(obj != nullptr);
19607 return obj.release();
19608 }
19609
19611 // JSON value storage //
19613
19640 union json_value
19641 {
19645 array_t* array;
19647 string_t* string;
19649 binary_t* binary;
19651 boolean_t boolean;
19653 number_integer_t number_integer;
19655 number_unsigned_t number_unsigned;
19657 number_float_t number_float;
19658
19660 json_value() = default;
19662 json_value(boolean_t v) noexcept : boolean(v) {}
19664 json_value(number_integer_t v) noexcept : number_integer(v) {}
19666 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
19668 json_value(number_float_t v) noexcept : number_float(v) {}
19670 json_value(value_t t)
19671 {
19672 switch (t)
19673 {
19674 case value_t::object:
19675 {
19676 object = create<object_t>();
19677 break;
19678 }
19679
19680 case value_t::array:
19681 {
19682 array = create<array_t>();
19683 break;
19684 }
19685
19686 case value_t::string:
19687 {
19688 string = create<string_t>("");
19689 break;
19690 }
19691
19692 case value_t::binary:
19693 {
19694 binary = create<binary_t>();
19695 break;
19696 }
19697
19698 case value_t::boolean:
19699 {
19700 boolean = static_cast<boolean_t>(false);
19701 break;
19702 }
19703
19704 case value_t::number_integer:
19705 {
19706 number_integer = static_cast<number_integer_t>(0);
19707 break;
19708 }
19709
19710 case value_t::number_unsigned:
19711 {
19712 number_unsigned = static_cast<number_unsigned_t>(0);
19713 break;
19714 }
19715
19716 case value_t::number_float:
19717 {
19718 number_float = static_cast<number_float_t>(0.0);
19719 break;
19720 }
19721
19722 case value_t::null:
19723 {
19724 object = nullptr; // silence warning, see #821
19725 break;
19726 }
19727
19728 case value_t::discarded:
19729 default:
19730 {
19731 object = nullptr; // silence warning, see #821
19732 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
19733 {
19734 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.2", nullptr)); // LCOV_EXCL_LINE
19735 }
19736 break;
19737 }
19738 }
19739 }
19740
19742 json_value(const string_t& value) : string(create<string_t>(value)) {}
19743
19745 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19746
19748 json_value(const object_t& value) : object(create<object_t>(value)) {}
19749
19751 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19752
19754 json_value(const array_t& value) : array(create<array_t>(value)) {}
19755
19757 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19758
19760 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19761
19763 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19764
19766 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19767
19769 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19770
19771 void destroy(value_t t)
19772 {
19773 if (
19774 (t == value_t::object && object == nullptr) ||
19775 (t == value_t::array && array == nullptr) ||
19776 (t == value_t::string && string == nullptr) ||
19777 (t == value_t::binary && binary == nullptr)
19778 )
19779 {
19780 //not initialized (e.g. due to exception in the ctor)
19781 return;
19782 }
19783 if (t == value_t::array || t == value_t::object)
19784 {
19785 // flatten the current json_value to a heap-allocated stack
19786 std::vector<basic_json> stack;
19787
19788 // move the top-level items to stack
19789 if (t == value_t::array)
19790 {
19791 stack.reserve(array->size());
19792 std::move(array->begin(), array->end(), std::back_inserter(stack));
19793 }
19794 else
19795 {
19796 stack.reserve(object->size());
19797 for (auto&& it : *object)
19798 {
19799 stack.push_back(std::move(it.second));
19800 }
19801 }
19802
19803 while (!stack.empty())
19804 {
19805 // move the last item to local variable to be processed
19806 basic_json current_item(std::move(stack.back()));
19807 stack.pop_back();
19808
19809 // if current_item is array/object, move
19810 // its children to the stack to be processed later
19811 if (current_item.is_array())
19812 {
19813 std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
19814
19815 current_item.m_data.m_value.array->clear();
19816 }
19817 else if (current_item.is_object())
19818 {
19819 for (auto&& it : *current_item.m_data.m_value.object)
19820 {
19821 stack.push_back(std::move(it.second));
19822 }
19823
19824 current_item.m_data.m_value.object->clear();
19825 }
19826
19827 // it's now safe that current_item get destructed
19828 // since it doesn't have any children
19829 }
19830 }
19831
19832 switch (t)
19833 {
19834 case value_t::object:
19835 {
19836 AllocatorType<object_t> alloc;
19837 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19838 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19839 break;
19840 }
19841
19842 case value_t::array:
19843 {
19844 AllocatorType<array_t> alloc;
19845 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19846 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19847 break;
19848 }
19849
19850 case value_t::string:
19851 {
19852 AllocatorType<string_t> alloc;
19853 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19854 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19855 break;
19856 }
19857
19858 case value_t::binary:
19859 {
19860 AllocatorType<binary_t> alloc;
19861 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19862 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19863 break;
19864 }
19865
19866 case value_t::null:
19867 case value_t::boolean:
19868 case value_t::number_integer:
19869 case value_t::number_unsigned:
19870 case value_t::number_float:
19871 case value_t::discarded:
19872 default:
19873 {
19874 break;
19875 }
19876 }
19877 }
19878 };
19879
19880private:
19899 void assert_invariant(bool check_parents = true) const noexcept
19900 {
19901 JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
19902 JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
19903 JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
19904 JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
19905
19906#if JSON_DIAGNOSTICS
19907 JSON_TRY
19908 {
19909 // cppcheck-suppress assertWithSideEffect
19910 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json& j)
19911 {
19912 return j.m_parent == this;
19913 }));
19914 }
19915 JSON_CATCH(...) {} // LCOV_EXCL_LINE
19916#endif
19917 static_cast<void>(check_parents);
19918 }
19919
19920 void set_parents()
19921 {
19922#if JSON_DIAGNOSTICS
19923 switch (m_data.m_type)
19924 {
19925 case value_t::array:
19926 {
19927 for (auto& element : *m_data.m_value.array)
19928 {
19929 element.m_parent = this;
19930 }
19931 break;
19932 }
19933
19934 case value_t::object:
19935 {
19936 for (auto& element : *m_data.m_value.object)
19937 {
19938 element.second.m_parent = this;
19939 }
19940 break;
19941 }
19942
19943 case value_t::null:
19944 case value_t::string:
19945 case value_t::boolean:
19946 case value_t::number_integer:
19947 case value_t::number_unsigned:
19948 case value_t::number_float:
19949 case value_t::binary:
19950 case value_t::discarded:
19951 default:
19952 break;
19953 }
19954#endif
19955 }
19956
19957 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
19958 {
19959#if JSON_DIAGNOSTICS
19960 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
19961 {
19962 (it + i)->m_parent = this;
19963 }
19964#else
19965 static_cast<void>(count_set_parents);
19966#endif
19967 return it;
19968 }
19969
19970 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
19971 {
19972#if JSON_DIAGNOSTICS
19973 if (old_capacity != static_cast<std::size_t>(-1))
19974 {
19975 // see https://github.com/nlohmann/json/issues/2838
19976 JSON_ASSERT(type() == value_t::array);
19977 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
19978 {
19979 // capacity has changed: update all parents
19980 set_parents();
19981 return j;
19982 }
19983 }
19984
19985 // ordered_json uses a vector internally, so pointers could have
19986 // been invalidated; see https://github.com/nlohmann/json/issues/2962
19987#ifdef JSON_HEDLEY_MSVC_VERSION
19988#pragma warning(push )
19989#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19990#endif
19992 {
19993 set_parents();
19994 return j;
19995 }
19996#ifdef JSON_HEDLEY_MSVC_VERSION
19997#pragma warning( pop )
19998#endif
19999
20000 j.m_parent = this;
20001#else
20002 static_cast<void>(j);
20003 static_cast<void>(old_capacity);
20004#endif
20005 return j;
20006 }
20007
20008public:
20010 // JSON parser callback //
20012
20016
20020
20022 // constructors //
20024
20029
20033 : m_data(v)
20034 {
20035 assert_invariant();
20036 }
20037
20040 basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
20041 : basic_json(value_t::null)
20042 {
20043 assert_invariant();
20044 }
20045
20048 template < typename CompatibleType,
20052 basic_json(CompatibleType&& val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20053 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20054 std::forward<CompatibleType>(val))))
20055 {
20056 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20057 set_parents();
20058 assert_invariant();
20059 }
20060
20063 template < typename BasicJsonType,
20065 detail::is_basic_json<BasicJsonType>::value && !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
20066 basic_json(const BasicJsonType& val)
20067 {
20068 using other_boolean_t = typename BasicJsonType::boolean_t;
20069 using other_number_float_t = typename BasicJsonType::number_float_t;
20070 using other_number_integer_t = typename BasicJsonType::number_integer_t;
20071 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20072 using other_string_t = typename BasicJsonType::string_t;
20073 using other_object_t = typename BasicJsonType::object_t;
20074 using other_array_t = typename BasicJsonType::array_t;
20075 using other_binary_t = typename BasicJsonType::binary_t;
20076
20077 switch (val.type())
20078 {
20079 case value_t::boolean:
20080 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20081 break;
20082 case value_t::number_float:
20083 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20084 break;
20085 case value_t::number_integer:
20086 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20087 break;
20088 case value_t::number_unsigned:
20089 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20090 break;
20091 case value_t::string:
20092 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20093 break;
20094 case value_t::object:
20095 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20096 break;
20097 case value_t::array:
20098 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20099 break;
20100 case value_t::binary:
20101 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20102 break;
20103 case value_t::null:
20104 *this = nullptr;
20105 break;
20106 case value_t::discarded:
20107 m_data.m_type = value_t::discarded;
20108 break;
20109 default: // LCOV_EXCL_LINE
20110 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20111 }
20112 JSON_ASSERT(m_data.m_type == val.type());
20113 set_parents();
20114 assert_invariant();
20115 }
20116
20120 bool type_deduction = true,
20121 value_t manual_type = value_t::array)
20122 {
20123 // check if each element is an array with two elements whose first
20124 // element is a string
20125 bool is_an_object = std::all_of(init.begin(), init.end(),
20126 [](const detail::json_ref<basic_json>& element_ref)
20127 {
20128 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
20129 });
20130
20131 // adjust type if type deduction is not wanted
20132 if (!type_deduction)
20133 {
20134 // if array is wanted, do not create an object though possible
20135 if (manual_type == value_t::array)
20136 {
20137 is_an_object = false;
20138 }
20139
20140 // if object is wanted but impossible, throw an exception
20141 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20142 {
20143 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20144 }
20145 }
20146
20147 if (is_an_object)
20148 {
20149 // the initializer list is a list of pairs -> create object
20150 m_data.m_type = value_t::object;
20151 m_data.m_value = value_t::object;
20152
20153 for (auto& element_ref : init)
20154 {
20155 auto element = element_ref.moved_or_copied();
20156 m_data.m_value.object->emplace(
20157 std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
20158 std::move((*element.m_data.m_value.array)[1]));
20159 }
20160 }
20161 else
20162 {
20163 // the initializer list describes an array -> create array
20164 m_data.m_type = value_t::array;
20165 m_data.m_value.array = create<array_t>(init.begin(), init.end());
20166 }
20167
20168 set_parents();
20169 assert_invariant();
20170 }
20171
20175 static basic_json binary(const typename binary_t::container_type& init)
20176 {
20177 auto res = basic_json();
20178 res.m_data.m_type = value_t::binary;
20179 res.m_data.m_value = init;
20180 return res;
20181 }
20182
20186 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20187 {
20188 auto res = basic_json();
20189 res.m_data.m_type = value_t::binary;
20190 res.m_data.m_value = binary_t(init, subtype);
20191 return res;
20192 }
20193
20197 static basic_json binary(typename binary_t::container_type&& init)
20198 {
20199 auto res = basic_json();
20200 res.m_data.m_type = value_t::binary;
20201 res.m_data.m_value = std::move(init);
20202 return res;
20203 }
20204
20208 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
20209 {
20210 auto res = basic_json();
20211 res.m_data.m_type = value_t::binary;
20212 res.m_data.m_value = binary_t(std::move(init), subtype);
20213 return res;
20214 }
20215
20220 {
20221 return basic_json(init, false, value_t::array);
20222 }
20223
20228 {
20229 return basic_json(init, false, value_t::object);
20230 }
20231
20235 m_data{ cnt, val }
20236 {
20237 set_parents();
20238 assert_invariant();
20239 }
20240
20243 template < class InputIT, typename std::enable_if <
20244 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
20245 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
20246 basic_json(InputIT first, InputIT last)
20247 {
20248 JSON_ASSERT(first.m_object != nullptr);
20249 JSON_ASSERT(last.m_object != nullptr);
20250
20251 // make sure iterator fits the current value
20252 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20253 {
20254 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
20255 }
20256
20257 // copy type from first iterator
20258 m_data.m_type = first.m_object->m_data.m_type;
20259
20260 // check if iterator range is complete for primitive values
20261 switch (m_data.m_type)
20262 {
20263 case value_t::boolean:
20264 case value_t::number_float:
20265 case value_t::number_integer:
20266 case value_t::number_unsigned:
20267 case value_t::string:
20268 {
20269 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20270 || !last.m_it.primitive_iterator.is_end()))
20271 {
20272 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20273 }
20274 break;
20275 }
20276
20277 case value_t::null:
20278 case value_t::object:
20279 case value_t::array:
20280 case value_t::binary:
20281 case value_t::discarded:
20282 default:
20283 break;
20284 }
20285
20286 switch (m_data.m_type)
20287 {
20288 case value_t::number_integer:
20289 {
20290 m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
20291 break;
20292 }
20293
20294 case value_t::number_unsigned:
20295 {
20296 m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
20297 break;
20298 }
20299
20300 case value_t::number_float:
20301 {
20302 m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
20303 break;
20304 }
20305
20306 case value_t::boolean:
20307 {
20308 m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
20309 break;
20310 }
20311
20312 case value_t::string:
20313 {
20314 m_data.m_value = *first.m_object->m_data.m_value.string;
20315 break;
20316 }
20317
20318 case value_t::object:
20319 {
20320 m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
20321 last.m_it.object_iterator);
20322 break;
20323 }
20324
20325 case value_t::array:
20326 {
20327 m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
20328 last.m_it.array_iterator);
20329 break;
20330 }
20331
20332 case value_t::binary:
20333 {
20334 m_data.m_value = *first.m_object->m_data.m_value.binary;
20335 break;
20336 }
20337
20338 case value_t::null:
20339 case value_t::discarded:
20340 default:
20341 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20342 }
20343
20344 set_parents();
20345 assert_invariant();
20346 }
20347
20348
20350 // other constructors and destructor //
20352
20353 template<typename JsonRef,
20355 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20356 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20357
20361 : json_base_class_t(other)
20362 {
20363 m_data.m_type = other.m_data.m_type;
20364 // check of passed value is valid
20365 other.assert_invariant();
20366
20367 switch (m_data.m_type)
20368 {
20369 case value_t::object:
20370 {
20371 m_data.m_value = *other.m_data.m_value.object;
20372 break;
20373 }
20374
20375 case value_t::array:
20376 {
20377 m_data.m_value = *other.m_data.m_value.array;
20378 break;
20379 }
20380
20381 case value_t::string:
20382 {
20383 m_data.m_value = *other.m_data.m_value.string;
20384 break;
20385 }
20386
20387 case value_t::boolean:
20388 {
20389 m_data.m_value = other.m_data.m_value.boolean;
20390 break;
20391 }
20392
20393 case value_t::number_integer:
20394 {
20395 m_data.m_value = other.m_data.m_value.number_integer;
20396 break;
20397 }
20398
20399 case value_t::number_unsigned:
20400 {
20401 m_data.m_value = other.m_data.m_value.number_unsigned;
20402 break;
20403 }
20404
20405 case value_t::number_float:
20406 {
20407 m_data.m_value = other.m_data.m_value.number_float;
20408 break;
20409 }
20410
20411 case value_t::binary:
20412 {
20413 m_data.m_value = *other.m_data.m_value.binary;
20414 break;
20415 }
20416
20417 case value_t::null:
20418 case value_t::discarded:
20419 default:
20420 break;
20421 }
20422
20423 set_parents();
20424 assert_invariant();
20425 }
20426
20429 basic_json(basic_json&& other) noexcept
20430 : json_base_class_t(std::move(other)),
20431 m_data(std::move(other.m_data))
20432 {
20433 // check that passed value is valid
20434 other.assert_invariant(false); // NOLINT(bugprone-use-after-move,hicpp-invalid-access-moved)
20435
20436 // invalidate payload
20437 other.m_data.m_type = value_t::null;
20438 other.m_data.m_value = {};
20439
20440 set_parents();
20441 assert_invariant();
20442 }
20443
20447 std::is_nothrow_move_constructible<value_t>::value&&
20448 std::is_nothrow_move_assignable<value_t>::value&&
20449 std::is_nothrow_move_constructible<json_value>::value&&
20450 std::is_nothrow_move_assignable<json_value>::value&&
20451 std::is_nothrow_move_assignable<json_base_class_t>::value
20452 )
20453 {
20454 // check that passed value is valid
20455 other.assert_invariant();
20456
20457 using std::swap;
20458 swap(m_data.m_type, other.m_data.m_type);
20459 swap(m_data.m_value, other.m_data.m_value);
20460 json_base_class_t::operator=(std::move(other));
20461
20462 set_parents();
20463 assert_invariant();
20464 return *this;
20465 }
20466
20469 ~basic_json() noexcept
20470 {
20471 assert_invariant(false);
20472 }
20473
20475
20476public:
20478 // object inspection //
20480
20484
20487 string_t dump(const int indent = -1,
20488 const char indent_char = ' ',
20489 const bool ensure_ascii = false,
20490 const error_handler_t error_handler = error_handler_t::strict) const
20491 {
20492 string_t result;
20493 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20494
20495 if (indent >= 0)
20496 {
20497 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20498 }
20499 else
20500 {
20501 s.dump(*this, false, ensure_ascii, 0);
20502 }
20503
20504 return result;
20505 }
20506
20509 constexpr value_t type() const noexcept
20510 {
20511 return m_data.m_type;
20512 }
20513
20516 constexpr bool is_primitive() const noexcept
20517 {
20518 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20519 }
20520
20523 constexpr bool is_structured() const noexcept
20524 {
20525 return is_array() || is_object();
20526 }
20527
20530 constexpr bool is_null() const noexcept
20531 {
20532 return m_data.m_type == value_t::null;
20533 }
20534
20537 constexpr bool is_boolean() const noexcept
20538 {
20539 return m_data.m_type == value_t::boolean;
20540 }
20541
20544 constexpr bool is_number() const noexcept
20545 {
20546 return is_number_integer() || is_number_float();
20547 }
20548
20551 constexpr bool is_number_integer() const noexcept
20552 {
20553 return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
20554 }
20555
20558 constexpr bool is_number_unsigned() const noexcept
20559 {
20560 return m_data.m_type == value_t::number_unsigned;
20561 }
20562
20565 constexpr bool is_number_float() const noexcept
20566 {
20567 return m_data.m_type == value_t::number_float;
20568 }
20569
20572 constexpr bool is_object() const noexcept
20573 {
20574 return m_data.m_type == value_t::object;
20575 }
20576
20579 constexpr bool is_array() const noexcept
20580 {
20581 return m_data.m_type == value_t::array;
20582 }
20583
20586 constexpr bool is_string() const noexcept
20587 {
20588 return m_data.m_type == value_t::string;
20589 }
20590
20593 constexpr bool is_binary() const noexcept
20594 {
20595 return m_data.m_type == value_t::binary;
20596 }
20597
20600 constexpr bool is_discarded() const noexcept
20601 {
20602 return m_data.m_type == value_t::discarded;
20603 }
20604
20607 constexpr operator value_t() const noexcept
20608 {
20609 return m_data.m_type;
20610 }
20611
20613
20614private:
20616 // value access //
20618
20620 boolean_t get_impl(boolean_t* /*unused*/) const
20621 {
20623 {
20624 return m_data.m_value.boolean;
20625 }
20626
20627 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20628 }
20629
20631 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20632 {
20633 return is_object() ? m_data.m_value.object : nullptr;
20634 }
20635
20637 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20638 {
20639 return is_object() ? m_data.m_value.object : nullptr;
20640 }
20641
20643 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20644 {
20645 return is_array() ? m_data.m_value.array : nullptr;
20646 }
20647
20649 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20650 {
20651 return is_array() ? m_data.m_value.array : nullptr;
20652 }
20653
20655 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20656 {
20657 return is_string() ? m_data.m_value.string : nullptr;
20658 }
20659
20661 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20662 {
20663 return is_string() ? m_data.m_value.string : nullptr;
20664 }
20665
20667 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20668 {
20669 return is_boolean() ? &m_data.m_value.boolean : nullptr;
20670 }
20671
20673 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20674 {
20675 return is_boolean() ? &m_data.m_value.boolean : nullptr;
20676 }
20677
20679 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20680 {
20681 return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20682 }
20683
20685 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20686 {
20687 return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20688 }
20689
20691 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20692 {
20693 return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20694 }
20695
20697 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20698 {
20699 return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20700 }
20701
20703 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20704 {
20705 return is_number_float() ? &m_data.m_value.number_float : nullptr;
20706 }
20707
20709 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20710 {
20711 return is_number_float() ? &m_data.m_value.number_float : nullptr;
20712 }
20713
20715 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20716 {
20717 return is_binary() ? m_data.m_value.binary : nullptr;
20718 }
20719
20721 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20722 {
20723 return is_binary() ? m_data.m_value.binary : nullptr;
20724 }
20725
20737 template<typename ReferenceType, typename ThisType>
20738 static ReferenceType get_ref_impl(ThisType& obj)
20739 {
20740 // delegate the call to get_ptr<>()
20741 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20742
20743 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20744 {
20745 return *ptr;
20746 }
20747
20748 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20749 }
20750
20751public:
20755
20758 template<typename PointerType, typename std::enable_if<
20759 std::is_pointer<PointerType>::value, int>::type = 0>
20760 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20761 {
20762 // delegate the call to get_impl_ptr<>()
20763 return get_impl_ptr(static_cast<PointerType>(nullptr));
20764 }
20765
20768 template < typename PointerType, typename std::enable_if <
20769 std::is_pointer<PointerType>::value&&
20770 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20771 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20772 {
20773 // delegate the call to get_impl_ptr<>() const
20774 return get_impl_ptr(static_cast<PointerType>(nullptr));
20775 }
20776
20777private:
20816 template < typename ValueType,
20820 int > = 0 >
20821 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20822 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20823 {
20824 auto ret = ValueType();
20825 JSONSerializer<ValueType>::from_json(*this, ret);
20826 return ret;
20827 }
20828
20859 template < typename ValueType,
20862 int > = 0 >
20863 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20864 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20865 {
20866 return JSONSerializer<ValueType>::from_json(*this);
20867 }
20868
20884 template < typename BasicJsonType,
20887 int > = 0 >
20888 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20889 {
20890 return *this;
20891 }
20892
20907 template<typename BasicJsonType,
20909 std::is_same<BasicJsonType, basic_json_t>::value,
20910 int> = 0>
20911 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20912 {
20913 return *this;
20914 }
20915
20920 template<typename PointerType,
20922 std::is_pointer<PointerType>::value,
20923 int> = 0>
20924 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20925 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20926 {
20927 // delegate the call to get_ptr
20928 return get_ptr<PointerType>();
20929 }
20930
20931public:
20955 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20956#if defined(JSON_HAS_CPP_14)
20957 constexpr
20958#endif
20959 auto get() const noexcept(
20960 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20961 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20962 {
20963 // we cannot static_assert on ValueTypeCV being non-const, because
20964 // there is support for get<const basic_json_t>(), which is why we
20965 // still need the uncvref
20966 static_assert(!std::is_reference<ValueTypeCV>::value,
20967 "get() cannot be used with reference types, you might want to use get_ref()");
20968 return get_impl<ValueType>(detail::priority_tag<4> {});
20969 }
20970
20998 template<typename PointerType, typename std::enable_if<
20999 std::is_pointer<PointerType>::value, int>::type = 0>
21000 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
21001 {
21002 // delegate the call to get_ptr
21003 return get_ptr<PointerType>();
21004 }
21005
21008 template < typename ValueType,
21012 int > = 0 >
21013 ValueType& get_to(ValueType& v) const noexcept(noexcept(
21014 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
21015 {
21016 JSONSerializer<ValueType>::from_json(*this, v);
21017 return v;
21018 }
21019
21020 // specialization to allow calling get_to with a basic_json value
21021 // see https://github.com/nlohmann/json/issues/2175
21022 template<typename ValueType,
21025 int> = 0>
21026 ValueType& get_to(ValueType& v) const
21027 {
21028 v = *this;
21029 return v;
21030 }
21031
21032 template <
21033 typename T, std::size_t N,
21034 typename Array = T(&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21037 Array get_to(T(&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21038 noexcept(noexcept(JSONSerializer<Array>::from_json(
21039 std::declval<const basic_json_t&>(), v)))
21040 {
21041 JSONSerializer<Array>::from_json(*this, v);
21042 return v;
21043 }
21044
21047 template<typename ReferenceType, typename std::enable_if<
21048 std::is_reference<ReferenceType>::value, int>::type = 0>
21049 ReferenceType get_ref()
21050 {
21051 // delegate call to get_ref_impl
21052 return get_ref_impl<ReferenceType>(*this);
21053 }
21054
21057 template < typename ReferenceType, typename std::enable_if <
21058 std::is_reference<ReferenceType>::value&&
21059 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21060 ReferenceType get_ref() const
21061 {
21062 // delegate call to get_ref_impl
21063 return get_ref_impl<ReferenceType>(*this);
21064 }
21065
21095 template < typename ValueType, typename std::enable_if <
21103#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21105#endif
21106#if defined(JSON_HAS_CPP_17)
21108#endif
21110 >::value, int >::type = 0 >
21111 JSON_EXPLICIT operator ValueType() const
21112 {
21113 // delegate the call to get<>() const
21114 return get<ValueType>();
21115 }
21116
21120 {
21121 if (!is_binary())
21122 {
21123 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21124 }
21125
21126 return *get_ptr<binary_t*>();
21127 }
21128
21131 const binary_t& get_binary() const
21132 {
21133 if (!is_binary())
21134 {
21135 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21136 }
21137
21138 return *get_ptr<const binary_t*>();
21139 }
21140
21142
21143
21145 // element access //
21147
21151
21155 {
21156 // at only works for arrays
21158 {
21159 JSON_TRY
21160 {
21161 return set_parent(m_data.m_value.array->at(idx));
21162 }
21163 JSON_CATCH(std::out_of_range&)
21164 {
21165 // create better exception explanation
21166 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21167 }
21168 }
21169 else
21170 {
21171 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21172 }
21173 }
21174
21178 {
21179 // at only works for arrays
21181 {
21182 JSON_TRY
21183 {
21184 return m_data.m_value.array->at(idx);
21185 }
21186 JSON_CATCH(std::out_of_range&)
21187 {
21188 // create better exception explanation
21189 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21190 }
21191 }
21192 else
21193 {
21194 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21195 }
21196 }
21197
21200 reference at(const typename object_t::key_type& key)
21201 {
21202 // at only works for objects
21204 {
21205 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21206 }
21207
21208 auto it = m_data.m_value.object->find(key);
21209 if (it == m_data.m_value.object->end())
21210 {
21211 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21212 }
21213 return set_parent(it->second);
21214 }
21215
21218 template<class KeyType, detail::enable_if_t<
21220 reference at(KeyType&& key)
21221 {
21222 // at only works for objects
21224 {
21225 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21226 }
21227
21228 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21229 if (it == m_data.m_value.object->end())
21230 {
21231 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21232 }
21233 return set_parent(it->second);
21234 }
21235
21238 const_reference at(const typename object_t::key_type& key) const
21239 {
21240 // at only works for objects
21242 {
21243 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21244 }
21245
21246 auto it = m_data.m_value.object->find(key);
21247 if (it == m_data.m_value.object->end())
21248 {
21249 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21250 }
21251 return it->second;
21252 }
21253
21256 template<class KeyType, detail::enable_if_t<
21258 const_reference at(KeyType&& key) const
21259 {
21260 // at only works for objects
21262 {
21263 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21264 }
21265
21266 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21267 if (it == m_data.m_value.object->end())
21268 {
21269 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21270 }
21271 return it->second;
21272 }
21273
21277 {
21278 // implicitly convert null value to an empty array
21279 if (is_null())
21280 {
21281 m_data.m_type = value_t::array;
21282 m_data.m_value.array = create<array_t>();
21283 assert_invariant();
21284 }
21285
21286 // operator[] only works for arrays
21288 {
21289 // fill up array with null values if given idx is outside range
21290 if (idx >= m_data.m_value.array->size())
21291 {
21292#if JSON_DIAGNOSTICS
21293 // remember array size & capacity before resizing
21294 const auto old_size = m_data.m_value.array->size();
21295 const auto old_capacity = m_data.m_value.array->capacity();
21296#endif
21297 m_data.m_value.array->resize(idx + 1);
21298
21299#if JSON_DIAGNOSTICS
21300 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
21301 {
21302 // capacity has changed: update all parents
21303 set_parents();
21304 }
21305 else
21306 {
21307 // set parent for values added above
21308 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21309 }
21310#endif
21311 assert_invariant();
21312 }
21313
21314 return m_data.m_value.array->operator[](idx);
21315 }
21316
21317 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21318 }
21319
21323 {
21324 // const operator[] only works for arrays
21326 {
21327 return m_data.m_value.array->operator[](idx);
21328 }
21329
21330 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21331 }
21332
21335 reference operator[](typename object_t::key_type key)
21336 {
21337 // implicitly convert null value to an empty object
21338 if (is_null())
21339 {
21340 m_data.m_type = value_t::object;
21341 m_data.m_value.object = create<object_t>();
21342 assert_invariant();
21343 }
21344
21345 // operator[] only works for objects
21347 {
21348 auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
21349 return set_parent(result.first->second);
21350 }
21351
21352 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21353 }
21354
21357 const_reference operator[](const typename object_t::key_type& key) const
21358 {
21359 // const operator[] only works for objects
21361 {
21362 auto it = m_data.m_value.object->find(key);
21363 JSON_ASSERT(it != m_data.m_value.object->end());
21364 return it->second;
21365 }
21366
21367 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21368 }
21369
21370 // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21371 // (they seemingly cannot be constrained to resolve the ambiguity)
21372 template<typename T>
21374 {
21375 return operator[](typename object_t::key_type(key));
21376 }
21377
21378 template<typename T>
21380 {
21381 return operator[](typename object_t::key_type(key));
21382 }
21383
21386 template<class KeyType, detail::enable_if_t<
21388 reference operator[](KeyType&& key)
21389 {
21390 // implicitly convert null value to an empty object
21391 if (is_null())
21392 {
21393 m_data.m_type = value_t::object;
21394 m_data.m_value.object = create<object_t>();
21395 assert_invariant();
21396 }
21397
21398 // operator[] only works for objects
21400 {
21401 auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21402 return set_parent(result.first->second);
21403 }
21404
21405 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21406 }
21407
21410 template<class KeyType, detail::enable_if_t<
21412 const_reference operator[](KeyType&& key) const
21413 {
21414 // const operator[] only works for objects
21416 {
21417 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21418 JSON_ASSERT(it != m_data.m_value.object->end());
21419 return it->second;
21420 }
21421
21422 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21423 }
21424
21425private:
21426 template<typename KeyType>
21427 using is_comparable_with_object_key = detail::is_comparable <
21428 object_comparator_t, const typename object_t::key_type&, KeyType >;
21429
21430 template<typename ValueType>
21431 using value_return_type = std::conditional <
21433 string_t, typename std::decay<ValueType>::type >;
21434
21435public:
21438 template < class ValueType, detail::enable_if_t <
21441 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21442 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21443 {
21444 // value only works for objects
21446 {
21447 // if key is found, return value and given default value otherwise
21448 const auto it = find(key);
21449 if (it != end())
21450 {
21451 return it->template get<ValueType>();
21452 }
21453
21454 return default_value;
21455 }
21456
21457 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21458 }
21459
21462 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21466 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21467 ReturnType value(const typename object_t::key_type& key, ValueType&& default_value) const
21468 {
21469 // value only works for objects
21471 {
21472 // if key is found, return value and given default value otherwise
21473 const auto it = find(key);
21474 if (it != end())
21475 {
21476 return it->template get<ReturnType>();
21477 }
21478
21479 return std::forward<ValueType>(default_value);
21480 }
21481
21482 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21483 }
21484
21487 template < class ValueType, class KeyType, detail::enable_if_t <
21490 && is_comparable_with_object_key<KeyType>::value
21492 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21493 ValueType value(KeyType&& key, const ValueType& default_value) const
21494 {
21495 // value only works for objects
21497 {
21498 // if key is found, return value and given default value otherwise
21499 const auto it = find(std::forward<KeyType>(key));
21500 if (it != end())
21501 {
21502 return it->template get<ValueType>();
21503 }
21504
21505 return default_value;
21506 }
21507
21508 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21509 }
21510
21513 template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
21517 && is_comparable_with_object_key<KeyType>::value
21519 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21520 ReturnType value(KeyType&& key, ValueType&& default_value) const
21521 {
21522 // value only works for objects
21524 {
21525 // if key is found, return value and given default value otherwise
21526 const auto it = find(std::forward<KeyType>(key));
21527 if (it != end())
21528 {
21529 return it->template get<ReturnType>();
21530 }
21531
21532 return std::forward<ValueType>(default_value);
21533 }
21534
21535 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21536 }
21537
21540 template < class ValueType, detail::enable_if_t <
21542 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21543 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21544 {
21545 // value only works for objects
21547 {
21548 // if pointer resolves a value, return it or use default value
21549 JSON_TRY
21550 {
21551 return ptr.get_checked(this).template get<ValueType>();
21552 }
21554 {
21555 return default_value;
21556 }
21557 }
21558
21559 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21560 }
21561
21564 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21567 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21568 ReturnType value(const json_pointer& ptr, ValueType&& default_value) const
21569 {
21570 // value only works for objects
21572 {
21573 // if pointer resolves a value, return it or use default value
21574 JSON_TRY
21575 {
21576 return ptr.get_checked(this).template get<ReturnType>();
21577 }
21579 {
21580 return std::forward<ValueType>(default_value);
21581 }
21582 }
21583
21584 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21585 }
21586
21587 template < class ValueType, class BasicJsonType, detail::enable_if_t <
21590 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21591 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21592 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21593 {
21594 return value(ptr.convert(), default_value);
21595 }
21596
21597 template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
21601 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21602 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21603 ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType&& default_value) const
21604 {
21605 return value(ptr.convert(), std::forward<ValueType>(default_value));
21606 }
21607
21611 {
21612 return *begin();
21613 }
21614
21618 {
21619 return *cbegin();
21620 }
21621
21625 {
21626 auto tmp = end();
21627 --tmp;
21628 return *tmp;
21629 }
21630
21634 {
21635 auto tmp = cend();
21636 --tmp;
21637 return *tmp;
21638 }
21639
21642 template < class IteratorType, detail::enable_if_t <
21643 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21644 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21645 IteratorType erase(IteratorType pos)
21646 {
21647 // make sure iterator fits the current value
21648 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21649 {
21650 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21651 }
21652
21653 IteratorType result = end();
21654
21655 switch (m_data.m_type)
21656 {
21657 case value_t::boolean:
21658 case value_t::number_float:
21659 case value_t::number_integer:
21660 case value_t::number_unsigned:
21661 case value_t::string:
21662 case value_t::binary:
21663 {
21664 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21665 {
21666 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21667 }
21668
21669 if (is_string())
21670 {
21671 AllocatorType<string_t> alloc;
21672 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21673 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21674 m_data.m_value.string = nullptr;
21675 }
21676 else if (is_binary())
21677 {
21678 AllocatorType<binary_t> alloc;
21679 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21680 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21681 m_data.m_value.binary = nullptr;
21682 }
21683
21684 m_data.m_type = value_t::null;
21685 assert_invariant();
21686 break;
21687 }
21688
21689 case value_t::object:
21690 {
21691 result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
21692 break;
21693 }
21694
21695 case value_t::array:
21696 {
21697 result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
21698 break;
21699 }
21700
21701 case value_t::null:
21702 case value_t::discarded:
21703 default:
21704 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21705 }
21706
21707 return result;
21708 }
21709
21712 template < class IteratorType, detail::enable_if_t <
21713 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21714 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21715 IteratorType erase(IteratorType first, IteratorType last)
21716 {
21717 // make sure iterator fits the current value
21718 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21719 {
21720 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21721 }
21722
21723 IteratorType result = end();
21724
21725 switch (m_data.m_type)
21726 {
21727 case value_t::boolean:
21728 case value_t::number_float:
21729 case value_t::number_integer:
21730 case value_t::number_unsigned:
21731 case value_t::string:
21732 case value_t::binary:
21733 {
21734 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21735 || !last.m_it.primitive_iterator.is_end()))
21736 {
21737 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21738 }
21739
21740 if (is_string())
21741 {
21742 AllocatorType<string_t> alloc;
21743 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21744 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21745 m_data.m_value.string = nullptr;
21746 }
21747 else if (is_binary())
21748 {
21749 AllocatorType<binary_t> alloc;
21750 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21751 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21752 m_data.m_value.binary = nullptr;
21753 }
21754
21755 m_data.m_type = value_t::null;
21756 assert_invariant();
21757 break;
21758 }
21759
21760 case value_t::object:
21761 {
21762 result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
21763 last.m_it.object_iterator);
21764 break;
21765 }
21766
21767 case value_t::array:
21768 {
21769 result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
21770 last.m_it.array_iterator);
21771 break;
21772 }
21773
21774 case value_t::null:
21775 case value_t::discarded:
21776 default:
21777 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21778 }
21779
21780 return result;
21781 }
21782
21783private:
21784 template < typename KeyType, detail::enable_if_t <
21786 size_type erase_internal(KeyType&& key)
21787 {
21788 // this erase only works for objects
21790 {
21791 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21792 }
21793
21794 return m_data.m_value.object->erase(std::forward<KeyType>(key));
21795 }
21796
21797 template < typename KeyType, detail::enable_if_t <
21799 size_type erase_internal(KeyType&& key)
21800 {
21801 // this erase only works for objects
21803 {
21804 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21805 }
21806
21807 const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21808 if (it != m_data.m_value.object->end())
21809 {
21810 m_data.m_value.object->erase(it);
21811 return 1;
21812 }
21813 return 0;
21814 }
21815
21816public:
21817
21820 size_type erase(const typename object_t::key_type& key)
21821 {
21822 // the indirection via erase_internal() is added to avoid making this
21823 // function a template and thus de-rank it during overload resolution
21824 return erase_internal(key);
21825 }
21826
21829 template<class KeyType, detail::enable_if_t<
21831 size_type erase(KeyType&& key)
21832 {
21833 return erase_internal(std::forward<KeyType>(key));
21834 }
21835
21838 void erase(const size_type idx)
21839 {
21840 // this erase only works for arrays
21842 {
21843 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21844 {
21845 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21846 }
21847
21848 m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
21849 }
21850 else
21851 {
21852 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21853 }
21854 }
21855
21857
21858
21860 // lookup //
21862
21865
21868 iterator find(const typename object_t::key_type& key)
21869 {
21870 auto result = end();
21871
21872 if (is_object())
21873 {
21874 result.m_it.object_iterator = m_data.m_value.object->find(key);
21875 }
21876
21877 return result;
21878 }
21879
21882 const_iterator find(const typename object_t::key_type& key) const
21883 {
21884 auto result = cend();
21885
21886 if (is_object())
21887 {
21888 result.m_it.object_iterator = m_data.m_value.object->find(key);
21889 }
21890
21891 return result;
21892 }
21893
21896 template<class KeyType, detail::enable_if_t<
21898 iterator find(KeyType&& key)
21899 {
21900 auto result = end();
21901
21902 if (is_object())
21903 {
21904 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
21905 }
21906
21907 return result;
21908 }
21909
21912 template<class KeyType, detail::enable_if_t<
21914 const_iterator find(KeyType&& key) const
21915 {
21916 auto result = cend();
21917
21918 if (is_object())
21919 {
21920 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
21921 }
21922
21923 return result;
21924 }
21925
21928 size_type count(const typename object_t::key_type& key) const
21929 {
21930 // return 0 for all nonobject types
21931 return is_object() ? m_data.m_value.object->count(key) : 0;
21932 }
21933
21936 template<class KeyType, detail::enable_if_t<
21938 size_type count(KeyType&& key) const
21939 {
21940 // return 0 for all nonobject types
21941 return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
21942 }
21943
21946 bool contains(const typename object_t::key_type& key) const
21947 {
21948 return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
21949 }
21950
21953 template<class KeyType, detail::enable_if_t<
21955 bool contains(KeyType&& key) const
21956 {
21957 return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
21958 }
21959
21962 bool contains(const json_pointer& ptr) const
21963 {
21964 return ptr.contains(this);
21965 }
21966
21967 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
21968 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21969 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
21970 {
21971 return ptr.contains(this);
21972 }
21973
21975
21976
21978 // iterators //
21980
21983
21986 iterator begin() noexcept
21987 {
21988 iterator result(this);
21989 result.set_begin();
21990 return result;
21991 }
21992
21995 const_iterator begin() const noexcept
21996 {
21997 return cbegin();
21998 }
21999
22002 const_iterator cbegin() const noexcept
22003 {
22004 const_iterator result(this);
22005 result.set_begin();
22006 return result;
22007 }
22008
22011 iterator end() noexcept
22012 {
22013 iterator result(this);
22014 result.set_end();
22015 return result;
22016 }
22017
22020 const_iterator end() const noexcept
22021 {
22022 return cend();
22023 }
22024
22027 const_iterator cend() const noexcept
22028 {
22029 const_iterator result(this);
22030 result.set_end();
22031 return result;
22032 }
22033
22037 {
22038 return reverse_iterator(end());
22039 }
22040
22044 {
22045 return crbegin();
22046 }
22047
22051 {
22052 return reverse_iterator(begin());
22053 }
22054
22058 {
22059 return crend();
22060 }
22061
22065 {
22066 return const_reverse_iterator(cend());
22067 }
22068
22072 {
22074 }
22075
22076public:
22083 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22084 {
22085 return ref.items();
22086 }
22087
22094 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22095 {
22096 return ref.items();
22097 }
22098
22101 iteration_proxy<iterator> items() noexcept
22102 {
22103 return iteration_proxy<iterator>(*this);
22104 }
22105
22108 iteration_proxy<const_iterator> items() const noexcept
22109 {
22110 return iteration_proxy<const_iterator>(*this);
22111 }
22112
22114
22115
22117 // capacity //
22119
22122
22125 bool empty() const noexcept
22126 {
22127 switch (m_data.m_type)
22128 {
22129 case value_t::null:
22130 {
22131 // null values are empty
22132 return true;
22133 }
22134
22135 case value_t::array:
22136 {
22137 // delegate call to array_t::empty()
22138 return m_data.m_value.array->empty();
22139 }
22140
22141 case value_t::object:
22142 {
22143 // delegate call to object_t::empty()
22144 return m_data.m_value.object->empty();
22145 }
22146
22147 case value_t::string:
22148 case value_t::boolean:
22149 case value_t::number_integer:
22150 case value_t::number_unsigned:
22151 case value_t::number_float:
22152 case value_t::binary:
22153 case value_t::discarded:
22154 default:
22155 {
22156 // all other types are nonempty
22157 return false;
22158 }
22159 }
22160 }
22161
22164 size_type size() const noexcept
22165 {
22166 switch (m_data.m_type)
22167 {
22168 case value_t::null:
22169 {
22170 // null values are empty
22171 return 0;
22172 }
22173
22174 case value_t::array:
22175 {
22176 // delegate call to array_t::size()
22177 return m_data.m_value.array->size();
22178 }
22179
22180 case value_t::object:
22181 {
22182 // delegate call to object_t::size()
22183 return m_data.m_value.object->size();
22184 }
22185
22186 case value_t::string:
22187 case value_t::boolean:
22188 case value_t::number_integer:
22189 case value_t::number_unsigned:
22190 case value_t::number_float:
22191 case value_t::binary:
22192 case value_t::discarded:
22193 default:
22194 {
22195 // all other types have size 1
22196 return 1;
22197 }
22198 }
22199 }
22200
22203 size_type max_size() const noexcept
22204 {
22205 switch (m_data.m_type)
22206 {
22207 case value_t::array:
22208 {
22209 // delegate call to array_t::max_size()
22210 return m_data.m_value.array->max_size();
22211 }
22212
22213 case value_t::object:
22214 {
22215 // delegate call to object_t::max_size()
22216 return m_data.m_value.object->max_size();
22217 }
22218
22219 case value_t::null:
22220 case value_t::string:
22221 case value_t::boolean:
22222 case value_t::number_integer:
22223 case value_t::number_unsigned:
22224 case value_t::number_float:
22225 case value_t::binary:
22226 case value_t::discarded:
22227 default:
22228 {
22229 // all other types have max_size() == size()
22230 return size();
22231 }
22232 }
22233 }
22234
22236
22237
22239 // modifiers //
22241
22244
22247 void clear() noexcept
22248 {
22249 switch (m_data.m_type)
22250 {
22251 case value_t::number_integer:
22252 {
22253 m_data.m_value.number_integer = 0;
22254 break;
22255 }
22256
22257 case value_t::number_unsigned:
22258 {
22259 m_data.m_value.number_unsigned = 0;
22260 break;
22261 }
22262
22263 case value_t::number_float:
22264 {
22265 m_data.m_value.number_float = 0.0;
22266 break;
22267 }
22268
22269 case value_t::boolean:
22270 {
22271 m_data.m_value.boolean = false;
22272 break;
22273 }
22274
22275 case value_t::string:
22276 {
22277 m_data.m_value.string->clear();
22278 break;
22279 }
22280
22281 case value_t::binary:
22282 {
22283 m_data.m_value.binary->clear();
22284 break;
22285 }
22286
22287 case value_t::array:
22288 {
22289 m_data.m_value.array->clear();
22290 break;
22291 }
22292
22293 case value_t::object:
22294 {
22295 m_data.m_value.object->clear();
22296 break;
22297 }
22298
22299 case value_t::null:
22300 case value_t::discarded:
22301 default:
22302 break;
22303 }
22304 }
22305
22309 {
22310 // push_back only works for null objects or arrays
22311 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22312 {
22313 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22314 }
22315
22316 // transform null object into an array
22317 if (is_null())
22318 {
22319 m_data.m_type = value_t::array;
22320 m_data.m_value = value_t::array;
22321 assert_invariant();
22322 }
22323
22324 // add element to array (move semantics)
22325 const auto old_capacity = m_data.m_value.array->capacity();
22326 m_data.m_value.array->push_back(std::move(val));
22327 set_parent(m_data.m_value.array->back(), old_capacity);
22328 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22329 }
22330
22334 {
22335 push_back(std::move(val));
22336 return *this;
22337 }
22338
22341 void push_back(const basic_json& val)
22342 {
22343 // push_back only works for null objects or arrays
22344 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22345 {
22346 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22347 }
22348
22349 // transform null object into an array
22350 if (is_null())
22351 {
22352 m_data.m_type = value_t::array;
22353 m_data.m_value = value_t::array;
22354 assert_invariant();
22355 }
22356
22357 // add element to array
22358 const auto old_capacity = m_data.m_value.array->capacity();
22359 m_data.m_value.array->push_back(val);
22360 set_parent(m_data.m_value.array->back(), old_capacity);
22361 }
22362
22366 {
22367 push_back(val);
22368 return *this;
22369 }
22370
22373 void push_back(const typename object_t::value_type& val)
22374 {
22375 // push_back only works for null objects or objects
22376 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22377 {
22378 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22379 }
22380
22381 // transform null object into an object
22382 if (is_null())
22383 {
22384 m_data.m_type = value_t::object;
22385 m_data.m_value = value_t::object;
22386 assert_invariant();
22387 }
22388
22389 // add element to object
22390 auto res = m_data.m_value.object->insert(val);
22391 set_parent(res.first->second);
22392 }
22393
22396 reference operator+=(const typename object_t::value_type& val)
22397 {
22398 push_back(val);
22399 return *this;
22400 }
22401
22405 {
22406 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22407 {
22408 basic_json&& key = init.begin()->moved_or_copied();
22409 push_back(typename object_t::value_type(
22410 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22411 }
22412 else
22413 {
22414 push_back(basic_json(init));
22415 }
22416 }
22417
22421 {
22422 push_back(init);
22423 return *this;
22424 }
22425
22428 template<class... Args>
22429 reference emplace_back(Args&& ... args)
22430 {
22431 // emplace_back only works for null objects or arrays
22432 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22433 {
22434 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22435 }
22436
22437 // transform null object into an array
22438 if (is_null())
22439 {
22440 m_data.m_type = value_t::array;
22441 m_data.m_value = value_t::array;
22442 assert_invariant();
22443 }
22444
22445 // add element to array (perfect forwarding)
22446 const auto old_capacity = m_data.m_value.array->capacity();
22447 m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
22448 return set_parent(m_data.m_value.array->back(), old_capacity);
22449 }
22450
22453 template<class... Args>
22454 std::pair<iterator, bool> emplace(Args&& ... args)
22455 {
22456 // emplace only works for null objects or arrays
22457 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22458 {
22459 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22460 }
22461
22462 // transform null object into an object
22463 if (is_null())
22464 {
22465 m_data.m_type = value_t::object;
22466 m_data.m_value = value_t::object;
22467 assert_invariant();
22468 }
22469
22470 // add element to array (perfect forwarding)
22471 auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
22472 set_parent(res.first->second);
22473
22474 // create result iterator and set iterator to the result of emplace
22475 auto it = begin();
22476 it.m_it.object_iterator = res.first;
22477
22478 // return pair of iterator and boolean
22479 return { it, res.second };
22480 }
22481
22485 template<typename... Args>
22487 {
22488 iterator result(this);
22489 JSON_ASSERT(m_data.m_value.array != nullptr);
22490
22491 auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
22492 m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22493 result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
22494
22495 // This could have been written as:
22496 // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22497 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22498
22499 set_parents();
22500 return result;
22501 }
22502
22506 {
22507 // insert only works for arrays
22509 {
22510 // check if iterator pos fits to this JSON value
22511 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22512 {
22513 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22514 }
22515
22516 // insert to array and return iterator
22517 return insert_iterator(pos, val);
22518 }
22519
22520 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22521 }
22522
22526 {
22527 return insert(pos, val);
22528 }
22529
22533 {
22534 // insert only works for arrays
22536 {
22537 // check if iterator pos fits to this JSON value
22538 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22539 {
22540 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22541 }
22542
22543 // insert to array and return iterator
22544 return insert_iterator(pos, cnt, val);
22545 }
22546
22547 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22548 }
22549
22553 {
22554 // insert only works for arrays
22556 {
22557 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22558 }
22559
22560 // check if iterator pos fits to this JSON value
22561 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22562 {
22563 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22564 }
22565
22566 // check if range iterators belong to the same JSON object
22567 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22568 {
22569 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22570 }
22571
22572 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22573 {
22574 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22575 }
22576
22577 // insert to array and return iterator
22578 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22579 }
22580
22584 {
22585 // insert only works for arrays
22587 {
22588 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22589 }
22590
22591 // check if iterator pos fits to this JSON value
22592 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22593 {
22594 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22595 }
22596
22597 // insert to array and return iterator
22598 return insert_iterator(pos, ilist.begin(), ilist.end());
22599 }
22600
22604 {
22605 // insert only works for objects
22607 {
22608 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22609 }
22610
22611 // check if range iterators belong to the same JSON object
22612 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22613 {
22614 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22615 }
22616
22617 // passed iterators must belong to objects
22618 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22619 {
22620 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22621 }
22622
22623 m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22624 }
22625
22628 void update(const_reference j, bool merge_objects = false)
22629 {
22630 update(j.begin(), j.end(), merge_objects);
22631 }
22632
22635 void update(const_iterator first, const_iterator last, bool merge_objects = false)
22636 {
22637 // implicitly convert null value to an empty object
22638 if (is_null())
22639 {
22640 m_data.m_type = value_t::object;
22641 m_data.m_value.object = create<object_t>();
22642 assert_invariant();
22643 }
22644
22646 {
22647 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22648 }
22649
22650 // check if range iterators belong to the same JSON object
22651 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22652 {
22653 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22654 }
22655
22656 // passed iterators must belong to objects
22657 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22658 {
22659 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22660 }
22661
22662 for (auto it = first; it != last; ++it)
22663 {
22664 if (merge_objects && it.value().is_object())
22665 {
22666 auto it2 = m_data.m_value.object->find(it.key());
22667 if (it2 != m_data.m_value.object->end())
22668 {
22669 it2->second.update(it.value(), true);
22670 continue;
22671 }
22672 }
22673 m_data.m_value.object->operator[](it.key()) = it.value();
22674#if JSON_DIAGNOSTICS
22675 m_data.m_value.object->operator[](it.key()).m_parent = this;
22676#endif
22677 }
22678 }
22679
22682 void swap(reference other) noexcept (
22683 std::is_nothrow_move_constructible<value_t>::value&&
22684 std::is_nothrow_move_assignable<value_t>::value&&
22685 std::is_nothrow_move_constructible<json_value>::value&&
22686 std::is_nothrow_move_assignable<json_value>::value
22687 )
22688 {
22689 std::swap(m_data.m_type, other.m_data.m_type);
22690 std::swap(m_data.m_value, other.m_data.m_value);
22691
22692 set_parents();
22693 other.set_parents();
22694 assert_invariant();
22695 }
22696
22699 friend void swap(reference left, reference right) noexcept (
22700 std::is_nothrow_move_constructible<value_t>::value&&
22701 std::is_nothrow_move_assignable<value_t>::value&&
22702 std::is_nothrow_move_constructible<json_value>::value&&
22703 std::is_nothrow_move_assignable<json_value>::value
22704 )
22705 {
22706 left.swap(right);
22707 }
22708
22711 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
22712 {
22713 // swap only works for arrays
22715 {
22716 using std::swap;
22717 swap(*(m_data.m_value.array), other);
22718 }
22719 else
22720 {
22721 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22722 }
22723 }
22724
22727 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
22728 {
22729 // swap only works for objects
22731 {
22732 using std::swap;
22733 swap(*(m_data.m_value.object), other);
22734 }
22735 else
22736 {
22737 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22738 }
22739 }
22740
22743 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
22744 {
22745 // swap only works for strings
22747 {
22748 using std::swap;
22749 swap(*(m_data.m_value.string), other);
22750 }
22751 else
22752 {
22753 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22754 }
22755 }
22756
22759 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
22760 {
22761 // swap only works for strings
22763 {
22764 using std::swap;
22765 swap(*(m_data.m_value.binary), other);
22766 }
22767 else
22768 {
22769 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22770 }
22771 }
22772
22775 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22776 {
22777 // swap only works for strings
22779 {
22780 using std::swap;
22781 swap(*(m_data.m_value.binary), other);
22782 }
22783 else
22784 {
22785 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22786 }
22787 }
22788
22790
22792 // lexicographical comparison operators //
22794
22797
22798 // note parentheses around operands are necessary; see
22799 // https://github.com/nlohmann/json/issues/1530
22800#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22801 const auto lhs_type = lhs.type(); \
22802 const auto rhs_type = rhs.type(); \
22803 \
22804 if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22805 { \
22806 switch (lhs_type) \
22807 { \
22808 case value_t::array: \
22809 return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
22810 \
22811 case value_t::object: \
22812 return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
22813 \
22814 case value_t::null: \
22815 return (null_result); \
22816 \
22817 case value_t::string: \
22818 return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
22819 \
22820 case value_t::boolean: \
22821 return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
22822 \
22823 case value_t::number_integer: \
22824 return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
22825 \
22826 case value_t::number_unsigned: \
22827 return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
22828 \
22829 case value_t::number_float: \
22830 return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
22831 \
22832 case value_t::binary: \
22833 return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
22834 \
22835 case value_t::discarded: \
22836 default: \
22837 return (unordered_result); \
22838 } \
22839 } \
22840 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22841 { \
22842 return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
22843 } \
22844 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22845 { \
22846 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
22847 } \
22848 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22849 { \
22850 return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
22851 } \
22852 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22853 { \
22854 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
22855 } \
22856 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22857 { \
22858 return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
22859 } \
22860 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22861 { \
22862 return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
22863 } \
22864 else if(compares_unordered(lhs, rhs))\
22865 {\
22866 return (unordered_result);\
22867 }\
22868 \
22869 return (default_result);
22870
22872 // returns true if:
22873 // - any operand is NaN and the other operand is of number type
22874 // - any operand is discarded
22875 // in legacy mode, discarded values are considered ordered if
22876 // an operation is computed as an odd number of inverses of others
22877 static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22878 {
22879 if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
22880 || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
22881 {
22882 return true;
22883 }
22884#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22885 return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22886#else
22887 static_cast<void>(inverse);
22888 return lhs.is_discarded() || rhs.is_discarded();
22889#endif
22890 }
22891
22892private:
22893 bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22894 {
22895 return compares_unordered(*this, rhs, inverse);
22896 }
22897
22898public:
22899#if JSON_HAS_THREE_WAY_COMPARISON
22902 bool operator==(const_reference rhs) const noexcept
22903 {
22904#ifdef __GNUC__
22905#pragma GCC diagnostic push
22906#pragma GCC diagnostic ignored "-Wfloat-equal"
22907#endif
22908 const_reference lhs = *this;
22909 JSON_IMPLEMENT_OPERATOR(== , true, false, false)
22910#ifdef __GNUC__
22911#pragma GCC diagnostic pop
22912#endif
22913 }
22914
22917 template<typename ScalarType>
22918 requires std::is_scalar_v<ScalarType>
22919 bool operator==(ScalarType rhs) const noexcept
22920 {
22921 return *this == basic_json(rhs);
22922 }
22923
22926 bool operator!=(const_reference rhs) const noexcept
22927 {
22928 if (compares_unordered(rhs, true))
22929 {
22930 return false;
22931 }
22932 return !operator==(rhs);
22933 }
22934
22937 std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
22938 {
22939 const_reference lhs = *this;
22940 // default_result is used if we cannot compare values. In that case,
22941 // we compare types.
22942 JSON_IMPLEMENT_OPERATOR(<=> , // *NOPAD*
22943 std::partial_ordering::equivalent,
22944 std::partial_ordering::unordered,
22945 lhs_type <=> rhs_type) // *NOPAD*
22946 }
22947
22950 template<typename ScalarType>
22951 requires std::is_scalar_v<ScalarType>
22952 std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
22953 {
22954 return *this <=> basic_json(rhs); // *NOPAD*
22955 }
22956
22957#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22958 // all operators that are computed as an odd number of inverses of others
22959 // need to be overloaded to emulate the legacy comparison behavior
22960
22964 bool operator<=(const_reference rhs) const noexcept
22965 {
22966 if (compares_unordered(rhs, true))
22967 {
22968 return false;
22969 }
22970 return !(rhs < *this);
22971 }
22972
22975 template<typename ScalarType>
22976 requires std::is_scalar_v<ScalarType>
22977 bool operator<=(ScalarType rhs) const noexcept
22978 {
22979 return *this <= basic_json(rhs);
22980 }
22981
22985 bool operator>=(const_reference rhs) const noexcept
22986 {
22987 if (compares_unordered(rhs, true))
22988 {
22989 return false;
22990 }
22991 return !(*this < rhs);
22992 }
22993
22996 template<typename ScalarType>
22997 requires std::is_scalar_v<ScalarType>
22998 bool operator>=(ScalarType rhs) const noexcept
22999 {
23000 return *this >= basic_json(rhs);
23001 }
23002#endif
23003#else
23006 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23007 {
23008#ifdef __GNUC__
23009#pragma GCC diagnostic push
23010#pragma GCC diagnostic ignored "-Wfloat-equal"
23011#endif
23012 JSON_IMPLEMENT_OPERATOR(== , true, false, false)
23013#ifdef __GNUC__
23014#pragma GCC diagnostic pop
23015#endif
23016 }
23017
23020 template<typename ScalarType, typename std::enable_if<
23021 std::is_scalar<ScalarType>::value, int>::type = 0>
23022 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23023 {
23024 return lhs == basic_json(rhs);
23025 }
23026
23029 template<typename ScalarType, typename std::enable_if<
23030 std::is_scalar<ScalarType>::value, int>::type = 0>
23031 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23032 {
23033 return basic_json(lhs) == rhs;
23034 }
23035
23038 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23039 {
23040 if (compares_unordered(lhs, rhs, true))
23041 {
23042 return false;
23043 }
23044 return !(lhs == rhs);
23045 }
23046
23049 template<typename ScalarType, typename std::enable_if<
23050 std::is_scalar<ScalarType>::value, int>::type = 0>
23051 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23052 {
23053 return lhs != basic_json(rhs);
23054 }
23055
23058 template<typename ScalarType, typename std::enable_if<
23059 std::is_scalar<ScalarType>::value, int>::type = 0>
23060 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23061 {
23062 return basic_json(lhs) != rhs;
23063 }
23064
23067 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23068 {
23069 // default_result is used if we cannot compare values. In that case,
23070 // we compare types. Note we have to call the operator explicitly,
23071 // because MSVC has problems otherwise.
23072 JSON_IMPLEMENT_OPERATOR(< , false, false, operator<(lhs_type, rhs_type))
23073 }
23074
23077 template<typename ScalarType, typename std::enable_if<
23078 std::is_scalar<ScalarType>::value, int>::type = 0>
23079 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23080 {
23081 return lhs < basic_json(rhs);
23082 }
23083
23086 template<typename ScalarType, typename std::enable_if<
23087 std::is_scalar<ScalarType>::value, int>::type = 0>
23088 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23089 {
23090 return basic_json(lhs) < rhs;
23091 }
23092
23095 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23096 {
23097 if (compares_unordered(lhs, rhs, true))
23098 {
23099 return false;
23100 }
23101 return !(rhs < lhs);
23102 }
23103
23106 template<typename ScalarType, typename std::enable_if<
23107 std::is_scalar<ScalarType>::value, int>::type = 0>
23108 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23109 {
23110 return lhs <= basic_json(rhs);
23111 }
23112
23115 template<typename ScalarType, typename std::enable_if<
23116 std::is_scalar<ScalarType>::value, int>::type = 0>
23117 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23118 {
23119 return basic_json(lhs) <= rhs;
23120 }
23121
23124 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23125 {
23126 // double inverse
23127 if (compares_unordered(lhs, rhs))
23128 {
23129 return false;
23130 }
23131 return !(lhs <= rhs);
23132 }
23133
23136 template<typename ScalarType, typename std::enable_if<
23137 std::is_scalar<ScalarType>::value, int>::type = 0>
23138 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23139 {
23140 return lhs > basic_json(rhs);
23141 }
23142
23145 template<typename ScalarType, typename std::enable_if<
23146 std::is_scalar<ScalarType>::value, int>::type = 0>
23147 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23148 {
23149 return basic_json(lhs) > rhs;
23150 }
23151
23154 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23155 {
23156 if (compares_unordered(lhs, rhs, true))
23157 {
23158 return false;
23159 }
23160 return !(lhs < rhs);
23161 }
23162
23165 template<typename ScalarType, typename std::enable_if<
23166 std::is_scalar<ScalarType>::value, int>::type = 0>
23167 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23168 {
23169 return lhs >= basic_json(rhs);
23170 }
23171
23174 template<typename ScalarType, typename std::enable_if<
23175 std::is_scalar<ScalarType>::value, int>::type = 0>
23176 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23177 {
23178 return basic_json(lhs) >= rhs;
23179 }
23180#endif
23181
23182#undef JSON_IMPLEMENT_OPERATOR
23183
23185
23187 // serialization //
23189
23192#ifndef JSON_NO_IO
23195 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23196 {
23197 // read width member and use it as indentation parameter if nonzero
23198 const bool pretty_print = o.width() > 0;
23199 const auto indentation = pretty_print ? o.width() : 0;
23200
23201 // reset width to 0 for subsequent calls to this stream
23202 o.width(0);
23203
23204 // do the actual serialization
23205 serializer s(detail::output_adapter<char>(o), o.fill());
23206 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23207 return o;
23208 }
23209
23216 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23217 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23218 {
23219 return o << j;
23220 }
23221#endif // JSON_NO_IO
23223
23224
23226 // deserialization //
23228
23231
23234 template<typename InputType>
23236 static basic_json parse(InputType&& i,
23237 const parser_callback_t cb = nullptr,
23238 const bool allow_exceptions = true,
23239 const bool ignore_comments = false)
23240 {
23241 basic_json result;
23242 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23243 return result;
23244 }
23245
23248 template<typename IteratorType>
23250 static basic_json parse(IteratorType first,
23251 IteratorType last,
23252 const parser_callback_t cb = nullptr,
23253 const bool allow_exceptions = true,
23254 const bool ignore_comments = false)
23255 {
23256 basic_json result;
23257 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23258 return result;
23259 }
23260
23262 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23263 static basic_json parse(detail::span_input_adapter&& i,
23264 const parser_callback_t cb = nullptr,
23265 const bool allow_exceptions = true,
23266 const bool ignore_comments = false)
23267 {
23268 basic_json result;
23269 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23270 return result;
23271 }
23272
23275 template<typename InputType>
23276 static bool accept(InputType&& i,
23277 const bool ignore_comments = false)
23278 {
23279 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23280 }
23281
23284 template<typename IteratorType>
23285 static bool accept(IteratorType first, IteratorType last,
23286 const bool ignore_comments = false)
23287 {
23288 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23289 }
23290
23292 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23293 static bool accept(detail::span_input_adapter&& i,
23294 const bool ignore_comments = false)
23295 {
23296 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23297 }
23298
23301 template <typename InputType, typename SAX>
23303 static bool sax_parse(InputType&& i, SAX* sax,
23305 const bool strict = true,
23306 const bool ignore_comments = false)
23307 {
23308 auto ia = detail::input_adapter(std::forward<InputType>(i));
23309 return format == input_format_t::json
23310 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23311 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23312 }
23313
23316 template<class IteratorType, class SAX>
23318 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23320 const bool strict = true,
23321 const bool ignore_comments = false)
23322 {
23323 auto ia = detail::input_adapter(std::move(first), std::move(last));
23324 return format == input_format_t::json
23325 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23326 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23327 }
23328
23334 template <typename SAX>
23335 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23337 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23339 const bool strict = true,
23340 const bool ignore_comments = false)
23341 {
23342 auto ia = i.get();
23343 return format == input_format_t::json
23344 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23345 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23346 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23347 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23348 }
23349#ifndef JSON_NO_IO
23356 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23357 friend std::istream& operator<<(basic_json& j, std::istream& i)
23358 {
23359 return operator>>(i, j);
23360 }
23361
23364 friend std::istream& operator>>(std::istream& i, basic_json& j)
23365 {
23366 parser(detail::input_adapter(i)).parse(false, j);
23367 return i;
23368 }
23369#endif // JSON_NO_IO
23371
23373 // convenience functions //
23375
23379 const char* type_name() const noexcept
23380 {
23381 switch (m_data.m_type)
23382 {
23383 case value_t::null:
23384 return "null";
23385 case value_t::object:
23386 return "object";
23387 case value_t::array:
23388 return "array";
23389 case value_t::string:
23390 return "string";
23391 case value_t::boolean:
23392 return "boolean";
23393 case value_t::binary:
23394 return "binary";
23395 case value_t::discarded:
23396 return "discarded";
23397 case value_t::number_integer:
23398 case value_t::number_unsigned:
23399 case value_t::number_float:
23400 default:
23401 return "number";
23402 }
23403 }
23404
23405
23408 // member variables //
23410
23411 struct data
23412 {
23414 value_t m_type = value_t::null;
23415
23417 json_value m_value = {};
23418
23419 data(const value_t v)
23420 : m_type(v), m_value(v)
23421 {
23422 }
23423
23424 data(size_type cnt, const basic_json& val)
23425 : m_type(value_t::array)
23426 {
23427 m_value.array = create<array_t>(cnt, val);
23428 }
23429
23430 data() noexcept = default;
23431 data(data&&) noexcept = default;
23432 data(const data&) noexcept = delete;
23433 data& operator=(data&&) noexcept = delete;
23434 data& operator=(const data&) noexcept = delete;
23435
23436 ~data() noexcept
23437 {
23438 m_value.destroy(m_type);
23439 }
23440 };
23441
23443
23444#if JSON_DIAGNOSTICS
23446 basic_json* m_parent = nullptr;
23447#endif
23448
23450 // binary serialization/deserialization //
23452
23455
23456public:
23459 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23460 {
23461 std::vector<std::uint8_t> result;
23462 to_cbor(j, result);
23463 return result;
23464 }
23465
23469 {
23470 binary_writer<std::uint8_t>(o).write_cbor(j);
23471 }
23472
23476 {
23477 binary_writer<char>(o).write_cbor(j);
23478 }
23479
23482 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23483 {
23484 std::vector<std::uint8_t> result;
23485 to_msgpack(j, result);
23486 return result;
23487 }
23488
23492 {
23493 binary_writer<std::uint8_t>(o).write_msgpack(j);
23494 }
23495
23499 {
23500 binary_writer<char>(o).write_msgpack(j);
23501 }
23502
23505 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23506 const bool use_size = false,
23507 const bool use_type = false)
23508 {
23509 std::vector<std::uint8_t> result;
23510 to_ubjson(j, result, use_size, use_type);
23511 return result;
23512 }
23513
23517 const bool use_size = false, const bool use_type = false)
23518 {
23519 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23520 }
23521
23525 const bool use_size = false, const bool use_type = false)
23526 {
23527 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23528 }
23529
23532 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23533 const bool use_size = false,
23534 const bool use_type = false)
23535 {
23536 std::vector<std::uint8_t> result;
23537 to_bjdata(j, result, use_size, use_type);
23538 return result;
23539 }
23540
23544 const bool use_size = false, const bool use_type = false)
23545 {
23546 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23547 }
23548
23552 const bool use_size = false, const bool use_type = false)
23553 {
23554 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23555 }
23556
23559 static std::vector<std::uint8_t> to_bson(const basic_json& j)
23560 {
23561 std::vector<std::uint8_t> result;
23562 to_bson(j, result);
23563 return result;
23564 }
23565
23569 {
23570 binary_writer<std::uint8_t>(o).write_bson(j);
23571 }
23572
23576 {
23577 binary_writer<char>(o).write_bson(j);
23578 }
23579
23582 template<typename InputType>
23584 static basic_json from_cbor(InputType&& i,
23585 const bool strict = true,
23586 const bool allow_exceptions = true,
23587 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23588 {
23589 basic_json result;
23590 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23591 auto ia = detail::input_adapter(std::forward<InputType>(i));
23592 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23593 return res ? result : basic_json(value_t::discarded);
23594 }
23595
23598 template<typename IteratorType>
23600 static basic_json from_cbor(IteratorType first, IteratorType last,
23601 const bool strict = true,
23602 const bool allow_exceptions = true,
23603 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23604 {
23605 basic_json result;
23606 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23607 auto ia = detail::input_adapter(std::move(first), std::move(last));
23608 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23609 return res ? result : basic_json(value_t::discarded);
23610 }
23611
23612 template<typename T>
23614 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23615 static basic_json from_cbor(const T* ptr, std::size_t len,
23616 const bool strict = true,
23617 const bool allow_exceptions = true,
23618 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23619 {
23620 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23621 }
23622
23623
23625 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23626 static basic_json from_cbor(detail::span_input_adapter&& i,
23627 const bool strict = true,
23628 const bool allow_exceptions = true,
23629 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23630 {
23631 basic_json result;
23632 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23633 auto ia = i.get();
23634 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23635 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23636 return res ? result : basic_json(value_t::discarded);
23637 }
23638
23641 template<typename InputType>
23643 static basic_json from_msgpack(InputType&& i,
23644 const bool strict = true,
23645 const bool allow_exceptions = true)
23646 {
23647 basic_json result;
23648 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23649 auto ia = detail::input_adapter(std::forward<InputType>(i));
23650 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23651 return res ? result : basic_json(value_t::discarded);
23652 }
23653
23656 template<typename IteratorType>
23658 static basic_json from_msgpack(IteratorType first, IteratorType last,
23659 const bool strict = true,
23660 const bool allow_exceptions = true)
23661 {
23662 basic_json result;
23663 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23664 auto ia = detail::input_adapter(std::move(first), std::move(last));
23665 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23666 return res ? result : basic_json(value_t::discarded);
23667 }
23668
23669 template<typename T>
23671 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23672 static basic_json from_msgpack(const T* ptr, std::size_t len,
23673 const bool strict = true,
23674 const bool allow_exceptions = true)
23675 {
23676 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23677 }
23678
23680 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23681 static basic_json from_msgpack(detail::span_input_adapter&& i,
23682 const bool strict = true,
23683 const bool allow_exceptions = true)
23684 {
23685 basic_json result;
23686 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23687 auto ia = i.get();
23688 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23689 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23690 return res ? result : basic_json(value_t::discarded);
23691 }
23692
23695 template<typename InputType>
23697 static basic_json from_ubjson(InputType&& i,
23698 const bool strict = true,
23699 const bool allow_exceptions = true)
23700 {
23701 basic_json result;
23702 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23703 auto ia = detail::input_adapter(std::forward<InputType>(i));
23704 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23705 return res ? result : basic_json(value_t::discarded);
23706 }
23707
23710 template<typename IteratorType>
23712 static basic_json from_ubjson(IteratorType first, IteratorType last,
23713 const bool strict = true,
23714 const bool allow_exceptions = true)
23715 {
23716 basic_json result;
23717 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23718 auto ia = detail::input_adapter(std::move(first), std::move(last));
23719 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23720 return res ? result : basic_json(value_t::discarded);
23721 }
23722
23723 template<typename T>
23725 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23726 static basic_json from_ubjson(const T* ptr, std::size_t len,
23727 const bool strict = true,
23728 const bool allow_exceptions = true)
23729 {
23730 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23731 }
23732
23734 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23735 static basic_json from_ubjson(detail::span_input_adapter&& i,
23736 const bool strict = true,
23737 const bool allow_exceptions = true)
23738 {
23739 basic_json result;
23740 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23741 auto ia = i.get();
23742 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23743 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23744 return res ? result : basic_json(value_t::discarded);
23745 }
23746
23747
23750 template<typename InputType>
23752 static basic_json from_bjdata(InputType&& i,
23753 const bool strict = true,
23754 const bool allow_exceptions = true)
23755 {
23756 basic_json result;
23757 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23758 auto ia = detail::input_adapter(std::forward<InputType>(i));
23759 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23760 return res ? result : basic_json(value_t::discarded);
23761 }
23762
23765 template<typename IteratorType>
23767 static basic_json from_bjdata(IteratorType first, IteratorType last,
23768 const bool strict = true,
23769 const bool allow_exceptions = true)
23770 {
23771 basic_json result;
23772 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23773 auto ia = detail::input_adapter(std::move(first), std::move(last));
23774 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23775 return res ? result : basic_json(value_t::discarded);
23776 }
23777
23780 template<typename InputType>
23782 static basic_json from_bson(InputType&& i,
23783 const bool strict = true,
23784 const bool allow_exceptions = true)
23785 {
23786 basic_json result;
23787 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23788 auto ia = detail::input_adapter(std::forward<InputType>(i));
23789 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23790 return res ? result : basic_json(value_t::discarded);
23791 }
23792
23795 template<typename IteratorType>
23797 static basic_json from_bson(IteratorType first, IteratorType last,
23798 const bool strict = true,
23799 const bool allow_exceptions = true)
23800 {
23801 basic_json result;
23802 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23803 auto ia = detail::input_adapter(std::move(first), std::move(last));
23804 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23805 return res ? result : basic_json(value_t::discarded);
23806 }
23807
23808 template<typename T>
23810 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23811 static basic_json from_bson(const T* ptr, std::size_t len,
23812 const bool strict = true,
23813 const bool allow_exceptions = true)
23814 {
23815 return from_bson(ptr, ptr + len, strict, allow_exceptions);
23816 }
23817
23819 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23820 static basic_json from_bson(detail::span_input_adapter&& i,
23821 const bool strict = true,
23822 const bool allow_exceptions = true)
23823 {
23824 basic_json result;
23825 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23826 auto ia = i.get();
23827 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23828 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23829 return res ? result : basic_json(value_t::discarded);
23830 }
23832
23834 // JSON Pointer support //
23836
23839
23843 {
23844 return ptr.get_unchecked(this);
23845 }
23846
23847 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23848 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23849 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23850 {
23851 return ptr.get_unchecked(this);
23852 }
23853
23857 {
23858 return ptr.get_unchecked(this);
23859 }
23860
23861 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23862 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23863 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23864 {
23865 return ptr.get_unchecked(this);
23866 }
23867
23871 {
23872 return ptr.get_checked(this);
23873 }
23874
23875 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23876 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23877 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23878 {
23879 return ptr.get_checked(this);
23880 }
23881
23885 {
23886 return ptr.get_checked(this);
23887 }
23888
23889 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23890 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23891 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23892 {
23893 return ptr.get_checked(this);
23894 }
23895
23899 {
23900 basic_json result(value_t::object);
23901 json_pointer::flatten("", *this, result);
23902 return result;
23903 }
23904
23908 {
23909 return json_pointer::unflatten(*this);
23910 }
23911
23913
23915 // JSON Patch functions //
23917
23920
23923 void patch_inplace(const basic_json& json_patch)
23924 {
23925 basic_json& result = *this;
23926 // the valid JSON Patch operations
23927 enum class patch_operations { add, remove, replace, move, copy, test, invalid };
23928
23929 const auto get_op = [](const std::string& op)
23930 {
23931 if (op == "add")
23932 {
23933 return patch_operations::add;
23934 }
23935 if (op == "remove")
23936 {
23937 return patch_operations::remove;
23938 }
23939 if (op == "replace")
23940 {
23941 return patch_operations::replace;
23942 }
23943 if (op == "move")
23944 {
23945 return patch_operations::move;
23946 }
23947 if (op == "copy")
23948 {
23949 return patch_operations::copy;
23950 }
23951 if (op == "test")
23952 {
23953 return patch_operations::test;
23954 }
23955
23956 return patch_operations::invalid;
23957 };
23958
23959 // wrapper for "add" operation; add value at ptr
23960 const auto operation_add = [&result](json_pointer& ptr, basic_json val)
23961 {
23962 // adding to the root of the target document means replacing it
23963 if (ptr.empty())
23964 {
23965 result = val;
23966 return;
23967 }
23968
23969 // make sure the top element of the pointer exists
23970 json_pointer const top_pointer = ptr.top();
23971 if (top_pointer != ptr)
23972 {
23973 result.at(top_pointer);
23974 }
23975
23976 // get reference to parent of JSON pointer ptr
23977 const auto last_path = ptr.back();
23978 ptr.pop_back();
23979 // parent must exist when performing patch add per RFC6902 specs
23980 basic_json& parent = result.at(ptr);
23981
23982 switch (parent.m_data.m_type)
23983 {
23984 case value_t::null:
23985 case value_t::object:
23986 {
23987 // use operator[] to add value
23988 parent[last_path] = val;
23989 break;
23990 }
23991
23992 case value_t::array:
23993 {
23994 if (last_path == "-")
23995 {
23996 // special case: append to back
23997 parent.push_back(val);
23998 }
23999 else
24000 {
24001 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
24002 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24003 {
24004 // avoid undefined behavior
24005 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
24006 }
24007
24008 // default case: insert add offset
24009 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24010 }
24011 break;
24012 }
24013
24014 // if there exists a parent it cannot be primitive
24015 case value_t::string: // LCOV_EXCL_LINE
24016 case value_t::boolean: // LCOV_EXCL_LINE
24017 case value_t::number_integer: // LCOV_EXCL_LINE
24018 case value_t::number_unsigned: // LCOV_EXCL_LINE
24019 case value_t::number_float: // LCOV_EXCL_LINE
24020 case value_t::binary: // LCOV_EXCL_LINE
24021 case value_t::discarded: // LCOV_EXCL_LINE
24022 default: // LCOV_EXCL_LINE
24023 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
24024 }
24025 };
24026
24027 // wrapper for "remove" operation; remove value at ptr
24028 const auto operation_remove = [this, &result](json_pointer& ptr)
24029 {
24030 // get reference to parent of JSON pointer ptr
24031 const auto last_path = ptr.back();
24032 ptr.pop_back();
24033 basic_json& parent = result.at(ptr);
24034
24035 // remove child
24036 if (parent.is_object())
24037 {
24038 // perform range check
24039 auto it = parent.find(last_path);
24040 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24041 {
24042 parent.erase(it);
24043 }
24044 else
24045 {
24046 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
24047 }
24048 }
24049 else if (parent.is_array())
24050 {
24051 // note erase performs range check
24052 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
24053 }
24054 };
24055
24056 // type check: top level value must be an array
24057 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24058 {
24059 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
24060 }
24061
24062 // iterate and apply the operations
24063 for (const auto& val : json_patch)
24064 {
24065 // wrapper to get a value for an operation
24066 const auto get_value = [&val](const std::string& op,
24067 const std::string& member,
24068 bool string_type) -> basic_json&
24069 {
24070 // find value
24071 auto it = val.m_data.m_value.object->find(member);
24072
24073 // context-sensitive error message
24074 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
24075
24076 // check if desired value is present
24077 if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
24078 {
24079 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24080 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24081 }
24082
24083 // check if result is of type string
24084 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24085 {
24086 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24087 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24088 }
24089
24090 // no error: return value
24091 return it->second;
24092 };
24093
24094 // type check: every element of the array must be an object
24095 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24096 {
24097 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24098 }
24099
24100 // collect mandatory members
24101 const auto op = get_value("op", "op", true).template get<std::string>();
24102 const auto path = get_value(op, "path", true).template get<std::string>();
24103 json_pointer ptr(path);
24104
24105 switch (get_op(op))
24106 {
24107 case patch_operations::add:
24108 {
24109 operation_add(ptr, get_value("add", "value", false));
24110 break;
24111 }
24112
24113 case patch_operations::remove:
24114 {
24115 operation_remove(ptr);
24116 break;
24117 }
24118
24119 case patch_operations::replace:
24120 {
24121 // the "path" location must exist - use at()
24122 result.at(ptr) = get_value("replace", "value", false);
24123 break;
24124 }
24125
24126 case patch_operations::move:
24127 {
24128 const auto from_path = get_value("move", "from", true).template get<std::string>();
24129 json_pointer from_ptr(from_path);
24130
24131 // the "from" location must exist - use at()
24132 basic_json const v = result.at(from_ptr);
24133
24134 // The move operation is functionally identical to a
24135 // "remove" operation on the "from" location, followed
24136 // immediately by an "add" operation at the target
24137 // location with the value that was just removed.
24138 operation_remove(from_ptr);
24139 operation_add(ptr, v);
24140 break;
24141 }
24142
24143 case patch_operations::copy:
24144 {
24145 const auto from_path = get_value("copy", "from", true).template get<std::string>();
24146 const json_pointer from_ptr(from_path);
24147
24148 // the "from" location must exist - use at()
24149 basic_json const v = result.at(from_ptr);
24150
24151 // The copy is functionally identical to an "add"
24152 // operation at the target location using the value
24153 // specified in the "from" member.
24154 operation_add(ptr, v);
24155 break;
24156 }
24157
24158 case patch_operations::test:
24159 {
24160 bool success = false;
24161 JSON_TRY
24162 {
24163 // check if "value" matches the one at "path"
24164 // the "path" location must exist - use at()
24165 success = (result.at(ptr) == get_value("test", "value", false));
24166 }
24168 {
24169 // ignore out of range errors: success remains false
24170 }
24171
24172 // throw an exception if test fails
24173 if (JSON_HEDLEY_UNLIKELY(!success))
24174 {
24175 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
24176 }
24177
24178 break;
24179 }
24180
24181 case patch_operations::invalid:
24182 default:
24183 {
24184 // op must be "add", "remove", "replace", "move", "copy", or
24185 // "test"
24186 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
24187 }
24188 }
24189 }
24190 }
24191
24194 basic_json patch(const basic_json& json_patch) const
24195 {
24196 basic_json result = *this;
24197 result.patch_inplace(json_patch);
24198 return result;
24199 }
24200
24204 static basic_json diff(const basic_json& source, const basic_json& target,
24205 const std::string& path = "")
24206 {
24207 // the patch
24208 basic_json result(value_t::array);
24209
24210 // if the values are the same, return empty patch
24211 if (source == target)
24212 {
24213 return result;
24214 }
24215
24216 if (source.type() != target.type())
24217 {
24218 // different types: replace value
24219 result.push_back(
24220 {
24221 {"op", "replace"}, {"path", path}, {"value", target}
24222 });
24223 return result;
24224 }
24225
24226 switch (source.type())
24227 {
24228 case value_t::array:
24229 {
24230 // first pass: traverse common elements
24231 std::size_t i = 0;
24232 while (i < source.size() && i < target.size())
24233 {
24234 // recursive call to compare array values at index i
24235 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24236 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24237 ++i;
24238 }
24239
24240 // We now reached the end of at least one array
24241 // in a second pass, traverse the remaining elements
24242
24243 // remove my remaining elements
24244 const auto end_index = static_cast<difference_type>(result.size());
24245 while (i < source.size())
24246 {
24247 // add operations in reverse order to avoid invalid
24248 // indices
24249 result.insert(result.begin() + end_index, object(
24250 {
24251 {"op", "remove"},
24252 {"path", detail::concat(path, '/', std::to_string(i))}
24253 }));
24254 ++i;
24255 }
24256
24257 // add other remaining elements
24258 while (i < target.size())
24259 {
24260 result.push_back(
24261 {
24262 {"op", "add"},
24263 {"path", detail::concat(path, "/-")},
24264 {"value", target[i]}
24265 });
24266 ++i;
24267 }
24268
24269 break;
24270 }
24271
24272 case value_t::object:
24273 {
24274 // first pass: traverse this object's elements
24275 for (auto it = source.cbegin(); it != source.cend(); ++it)
24276 {
24277 // escape the key name to be used in a JSON patch
24278 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24279
24280 if (target.find(it.key()) != target.end())
24281 {
24282 // recursive call to compare object values at key it
24283 auto temp_diff = diff(it.value(), target[it.key()], path_key);
24284 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24285 }
24286 else
24287 {
24288 // found a key that is not in o -> remove it
24289 result.push_back(object(
24290 {
24291 {"op", "remove"}, {"path", path_key}
24292 }));
24293 }
24294 }
24295
24296 // second pass: traverse other object's elements
24297 for (auto it = target.cbegin(); it != target.cend(); ++it)
24298 {
24299 if (source.find(it.key()) == source.end())
24300 {
24301 // found a key that is not in this -> add it
24302 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24303 result.push_back(
24304 {
24305 {"op", "add"}, {"path", path_key},
24306 {"value", it.value()}
24307 });
24308 }
24309 }
24310
24311 break;
24312 }
24313
24314 case value_t::null:
24315 case value_t::string:
24316 case value_t::boolean:
24317 case value_t::number_integer:
24318 case value_t::number_unsigned:
24319 case value_t::number_float:
24320 case value_t::binary:
24321 case value_t::discarded:
24322 default:
24323 {
24324 // both primitive type: replace value
24325 result.push_back(
24326 {
24327 {"op", "replace"}, {"path", path}, {"value", target}
24328 });
24329 break;
24330 }
24331 }
24332
24333 return result;
24334 }
24336
24338 // JSON Merge Patch functions //
24340
24343
24346 void merge_patch(const basic_json& apply_patch)
24347 {
24348 if (apply_patch.is_object())
24349 {
24350 if (!is_object())
24351 {
24352 *this = object();
24353 }
24354 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24355 {
24356 if (it.value().is_null())
24357 {
24358 erase(it.key());
24359 }
24360 else
24361 {
24362 operator[](it.key()).merge_patch(it.value());
24363 }
24364 }
24365 }
24366 else
24367 {
24368 *this = apply_patch;
24369 }
24370 }
24371
24373};
24374
24379{
24380 return j.dump();
24381}
24382
24383inline namespace literals
24384{
24385 inline namespace json_literals
24386 {
24387
24391 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24392 {
24393 return nlohmann::json::parse(s, s + n);
24394 }
24395
24399 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24400 {
24401 return nlohmann::json::json_pointer(std::string(s, n));
24402 }
24403
24404 } // namespace json_literals
24405} // namespace literals
24407
24409// nonmember support //
24411
24412namespace std // NOLINT(cert-dcl58-cpp)
24413{
24414
24418 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
24419 {
24420 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
24421 {
24422 return nlohmann::detail::hash(j);
24423 }
24424 };
24425
24426 // specialization for std::less<value_t>
24427 template<>
24428 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24429 {
24434 bool operator()(::nlohmann::detail::value_t lhs,
24435 ::nlohmann::detail::value_t rhs) const noexcept
24436 {
24437#if JSON_HAS_THREE_WAY_COMPARISON
24438 return std::is_lt(lhs <=> rhs); // *NOPAD*
24439#else
24440 return ::nlohmann::detail::operator<(lhs, rhs);
24441#endif
24442 }
24443 };
24444
24445 // C++20 prohibit function specialization in the std namespace.
24446#ifndef JSON_HAS_CPP_20
24447
24451 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)
24452 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
24453 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
24454 {
24455 j1.swap(j2);
24456 }
24457
24458#endif
24459
24460} // namespace std
24461
24462#if JSON_USE_GLOBAL_UDLS
24463using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24464using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24465#endif
24466
24467// #include <nlohmann/detail/macro_unscope.hpp>
24468// __ _____ _____ _____
24469// __| | __| | | | JSON for Modern C++
24470// | | |__ | | | | | | version 3.11.2
24471// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24472//
24473// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24474// SPDX-License-Identifier: MIT
24475
24476
24477
24478// restore clang diagnostic settings
24479#if defined(__clang__)
24480#pragma clang diagnostic pop
24481#endif
24482
24483// clean up
24484#undef JSON_ASSERT
24485#undef JSON_INTERNAL_CATCH
24486#undef JSON_THROW
24487#undef JSON_PRIVATE_UNLESS_TESTED
24488#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24489#undef NLOHMANN_BASIC_JSON_TPL
24490#undef JSON_EXPLICIT
24491#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24492#undef JSON_INLINE_VARIABLE
24493#undef JSON_NO_UNIQUE_ADDRESS
24494#undef JSON_DISABLE_ENUM_SERIALIZATION
24495#undef JSON_USE_GLOBAL_UDLS
24496
24497#ifndef JSON_TEST_KEEP_MACROS
24498#undef JSON_CATCH
24499#undef JSON_TRY
24500#undef JSON_HAS_CPP_11
24501#undef JSON_HAS_CPP_14
24502#undef JSON_HAS_CPP_17
24503#undef JSON_HAS_CPP_20
24504#undef JSON_HAS_FILESYSTEM
24505#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24506#undef JSON_HAS_THREE_WAY_COMPARISON
24507#undef JSON_HAS_RANGES
24508#undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24509#endif
24510
24511// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24512// __ _____ _____ _____
24513// __| | __| | | | JSON for Modern C++
24514// | | |__ | | | | | | version 3.11.2
24515// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24516//
24517// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24518// SPDX-License-Identifier: MIT
24519
24520
24521
24522#undef JSON_HEDLEY_ALWAYS_INLINE
24523#undef JSON_HEDLEY_ARM_VERSION
24524#undef JSON_HEDLEY_ARM_VERSION_CHECK
24525#undef JSON_HEDLEY_ARRAY_PARAM
24526#undef JSON_HEDLEY_ASSUME
24527#undef JSON_HEDLEY_BEGIN_C_DECLS
24528#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24529#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24530#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24531#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24532#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24533#undef JSON_HEDLEY_CLANG_HAS_FEATURE
24534#undef JSON_HEDLEY_CLANG_HAS_WARNING
24535#undef JSON_HEDLEY_COMPCERT_VERSION
24536#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24537#undef JSON_HEDLEY_CONCAT
24538#undef JSON_HEDLEY_CONCAT3
24539#undef JSON_HEDLEY_CONCAT3_EX
24540#undef JSON_HEDLEY_CONCAT_EX
24541#undef JSON_HEDLEY_CONST
24542#undef JSON_HEDLEY_CONSTEXPR
24543#undef JSON_HEDLEY_CONST_CAST
24544#undef JSON_HEDLEY_CPP_CAST
24545#undef JSON_HEDLEY_CRAY_VERSION
24546#undef JSON_HEDLEY_CRAY_VERSION_CHECK
24547#undef JSON_HEDLEY_C_DECL
24548#undef JSON_HEDLEY_DEPRECATED
24549#undef JSON_HEDLEY_DEPRECATED_FOR
24550#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24551#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24552#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24553#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24554#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24555#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24556#undef JSON_HEDLEY_DIAGNOSTIC_POP
24557#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24558#undef JSON_HEDLEY_DMC_VERSION
24559#undef JSON_HEDLEY_DMC_VERSION_CHECK
24560#undef JSON_HEDLEY_EMPTY_BASES
24561#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24562#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24563#undef JSON_HEDLEY_END_C_DECLS
24564#undef JSON_HEDLEY_FLAGS
24565#undef JSON_HEDLEY_FLAGS_CAST
24566#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24567#undef JSON_HEDLEY_GCC_HAS_BUILTIN
24568#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24569#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24570#undef JSON_HEDLEY_GCC_HAS_EXTENSION
24571#undef JSON_HEDLEY_GCC_HAS_FEATURE
24572#undef JSON_HEDLEY_GCC_HAS_WARNING
24573#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24574#undef JSON_HEDLEY_GCC_VERSION
24575#undef JSON_HEDLEY_GCC_VERSION_CHECK
24576#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24577#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24578#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24579#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24580#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24581#undef JSON_HEDLEY_GNUC_HAS_FEATURE
24582#undef JSON_HEDLEY_GNUC_HAS_WARNING
24583#undef JSON_HEDLEY_GNUC_VERSION
24584#undef JSON_HEDLEY_GNUC_VERSION_CHECK
24585#undef JSON_HEDLEY_HAS_ATTRIBUTE
24586#undef JSON_HEDLEY_HAS_BUILTIN
24587#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24588#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24589#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24590#undef JSON_HEDLEY_HAS_EXTENSION
24591#undef JSON_HEDLEY_HAS_FEATURE
24592#undef JSON_HEDLEY_HAS_WARNING
24593#undef JSON_HEDLEY_IAR_VERSION
24594#undef JSON_HEDLEY_IAR_VERSION_CHECK
24595#undef JSON_HEDLEY_IBM_VERSION
24596#undef JSON_HEDLEY_IBM_VERSION_CHECK
24597#undef JSON_HEDLEY_IMPORT
24598#undef JSON_HEDLEY_INLINE
24599#undef JSON_HEDLEY_INTEL_CL_VERSION
24600#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24601#undef JSON_HEDLEY_INTEL_VERSION
24602#undef JSON_HEDLEY_INTEL_VERSION_CHECK
24603#undef JSON_HEDLEY_IS_CONSTANT
24604#undef JSON_HEDLEY_IS_CONSTEXPR_
24605#undef JSON_HEDLEY_LIKELY
24606#undef JSON_HEDLEY_MALLOC
24607#undef JSON_HEDLEY_MCST_LCC_VERSION
24608#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24609#undef JSON_HEDLEY_MESSAGE
24610#undef JSON_HEDLEY_MSVC_VERSION
24611#undef JSON_HEDLEY_MSVC_VERSION_CHECK
24612#undef JSON_HEDLEY_NEVER_INLINE
24613#undef JSON_HEDLEY_NON_NULL
24614#undef JSON_HEDLEY_NO_ESCAPE
24615#undef JSON_HEDLEY_NO_RETURN
24616#undef JSON_HEDLEY_NO_THROW
24617#undef JSON_HEDLEY_NULL
24618#undef JSON_HEDLEY_PELLES_VERSION
24619#undef JSON_HEDLEY_PELLES_VERSION_CHECK
24620#undef JSON_HEDLEY_PGI_VERSION
24621#undef JSON_HEDLEY_PGI_VERSION_CHECK
24622#undef JSON_HEDLEY_PREDICT
24623#undef JSON_HEDLEY_PRINTF_FORMAT
24624#undef JSON_HEDLEY_PRIVATE
24625#undef JSON_HEDLEY_PUBLIC
24626#undef JSON_HEDLEY_PURE
24627#undef JSON_HEDLEY_REINTERPRET_CAST
24628#undef JSON_HEDLEY_REQUIRE
24629#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24630#undef JSON_HEDLEY_REQUIRE_MSG
24631#undef JSON_HEDLEY_RESTRICT
24632#undef JSON_HEDLEY_RETURNS_NON_NULL
24633#undef JSON_HEDLEY_SENTINEL
24634#undef JSON_HEDLEY_STATIC_ASSERT
24635#undef JSON_HEDLEY_STATIC_CAST
24636#undef JSON_HEDLEY_STRINGIFY
24637#undef JSON_HEDLEY_STRINGIFY_EX
24638#undef JSON_HEDLEY_SUNPRO_VERSION
24639#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24640#undef JSON_HEDLEY_TINYC_VERSION
24641#undef JSON_HEDLEY_TINYC_VERSION_CHECK
24642#undef JSON_HEDLEY_TI_ARMCL_VERSION
24643#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24644#undef JSON_HEDLEY_TI_CL2000_VERSION
24645#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24646#undef JSON_HEDLEY_TI_CL430_VERSION
24647#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24648#undef JSON_HEDLEY_TI_CL6X_VERSION
24649#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24650#undef JSON_HEDLEY_TI_CL7X_VERSION
24651#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24652#undef JSON_HEDLEY_TI_CLPRU_VERSION
24653#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24654#undef JSON_HEDLEY_TI_VERSION
24655#undef JSON_HEDLEY_TI_VERSION_CHECK
24656#undef JSON_HEDLEY_UNAVAILABLE
24657#undef JSON_HEDLEY_UNLIKELY
24658#undef JSON_HEDLEY_UNPREDICTABLE
24659#undef JSON_HEDLEY_UNREACHABLE
24660#undef JSON_HEDLEY_UNREACHABLE_RETURN
24661#undef JSON_HEDLEY_VERSION
24662#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24663#undef JSON_HEDLEY_VERSION_DECODE_MINOR
24664#undef JSON_HEDLEY_VERSION_DECODE_REVISION
24665#undef JSON_HEDLEY_VERSION_ENCODE
24666#undef JSON_HEDLEY_WARNING
24667#undef JSON_HEDLEY_WARN_UNUSED_RESULT
24668#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24669#undef JSON_HEDLEY_FALL_THROUGH
24670
24671
24672
24673#endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::json json
Definition: ARX.cpp:8
a class to store JSON values
Definition: json.hpp:19312
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20586
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21820
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:21388
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22164
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23600
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23532
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20959
const_iterator end() const noexcept
returns an iterator to one past the last element
Definition: json.hpp:22020
reference back()
access the last element
Definition: json.hpp:21624
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.hpp:20052
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:22036
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:24194
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23379
const_reference front() const
access the first element
Definition: json.hpp:21617
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20579
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21568
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21938
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:19444
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23551
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:19387
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20551
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:19448
data(size_type cnt, const basic_json &val)
Definition: json.hpp:23424
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23797
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23543
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23842
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:19439
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22682
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:19431
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20523
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:21412
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:19426
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:22759
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:21049
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22203
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22628
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21060
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20600
JSON_PRIVATE_UNLESS_TESTED const_reference rhs
Definition: json.hpp:22877
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22420
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22308
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:21357
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22108
const_reference back() const
access the last element
Definition: json.hpp:21633
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21715
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22365
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23697
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:20186
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:22532
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23782
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:19455
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:19582
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:21220
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:22011
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20558
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22635
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:23559
const_reverse_iterator rbegin() const noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:22043
data m_data
Definition: json.hpp:23442
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22404
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:20019
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:20227
ValueType & get_to(ValueType &v) const
Definition: json.hpp:21026
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23498
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:21986
JSON_PRIVATE_UNLESS_TESTED const_reference bool inverse
Definition: json.hpp:22877
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:21467
const_iterator cend() const noexcept
returns an iterator to one past the last element
Definition: json.hpp:22027
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23752
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23884
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:20197
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:20040
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23584
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:23898
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23712
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:21831
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:21131
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:22552
void patch_inplace(const basic_json &json_patch)
applies a JSON patch in-place without copying the object
Definition: json.hpp:23923
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21520
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:24204
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23856
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:19558
value_type & reference
the type of an element reference
Definition: json.hpp:19424
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21955
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23468
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23575
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:21868
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:20175
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:21258
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:19463
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:20234
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:21882
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23459
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21645
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:22505
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:19578
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21442
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:19434
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:19437
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:20487
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24346
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:21013
reference operator[](T *key)
Definition: json.hpp:21373
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21154
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:21898
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20565
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22050
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23505
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23870
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:19566
detail::value_t value_t
Definition: json.hpp:19377
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.hpp:19545
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22396
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:22002
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:21335
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20771
~basic_json() noexcept
destructor
Definition: json.hpp:20469
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22071
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:20119
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:22775
binary_t & get_binary()
get a binary value
Definition: json.hpp:21119
const_iterator begin() const noexcept
returns an iterator to the first element
Definition: json.hpp:21995
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20544
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:22603
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23643
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:21000
const_reference operator[](T *key) const
Definition: json.hpp:21379
data(const value_t v)
Definition: json.hpp:23419
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21276
basic_json(const JsonRef &ref)
Definition: json.hpp:20356
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:19381
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value &&std::is_nothrow_move_assignable< json_base_class_t >::value)
copy assignment
Definition: json.hpp:20446
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:22083
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23524
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:21037
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:19570
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20760
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:21238
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20593
void swap(object_t &other)
exchanges the values
Definition: json.hpp:22727
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:23907
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:22583
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:20208
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22101
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22125
void swap(array_t &other)
exchanges the values
Definition: json.hpp:22711
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21838
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22333
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:21962
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20509
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22429
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21543
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:20219
data() noexcept=default
StringType string_t
a type for a string
Definition: json.hpp:19562
friend class ::nlohmann::detail::parser
Definition: json.hpp:19322
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:19554
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22341
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21493
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21200
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23767
json_value m_value
the value of the current element
Definition: json.hpp:23417
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22064
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20537
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21928
reference front()
access the first element
Definition: json.hpp:21610
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20516
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20530
void clear() noexcept
clears the contents
Definition: json.hpp:22247
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23516
JSON_PRIVATE_UNLESS_TESTED const_reference bool static SAX bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
Definition: json.hpp:23303
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:20429
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:19442
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:20032
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21322
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:19429
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:22525
const_reverse_iterator rend() const noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22057
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:19574
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:23364
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23482
void swap(string_t &other)
exchanges the values
Definition: json.hpp:22743
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20066
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:19446
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22699
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21177
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:19586
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:20360
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22373
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22454
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23475
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20572
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23491
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23658
iterator insert_iterator(const_iterator pos, Args &&... args)
Helper for insertion of an iterator.
Definition: json.hpp:22486
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:20246
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:23357
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:21946
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23568
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:21914
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:19379
an internal type for a backed binary type
Definition: json.hpp:5825
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5865
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5831
std::uint64_t subtype_type
Definition: json.hpp:5828
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5859
BinaryType container_type
Definition: json.hpp:5827
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5853
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5841
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5880
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5846
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5887
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5836
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5872
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5894
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9146
binary_reader(const binary_reader &)=delete
binary_reader(binary_reader &&)=default
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9162
binary_reader & operator=(const binary_reader &)=delete
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:9183
binary_reader & operator=(binary_reader &&)=default
serialization to CBOR and MessagePack values
Definition: json.hpp:14992
void write_bson(const BasicJsonType &j)
Definition: json.hpp:15012
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16747
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16754
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:15003
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16776
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.hpp:15691
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:15365
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15041
general exception of the basic_json class
Definition: json.hpp:4306
const int id
the id of the exception
Definition: json.hpp:4315
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4326
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4321
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4309
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4332
Definition: json.hpp:6120
char char_type
Definition: json.hpp:6122
file_input_adapter(const file_input_adapter &)=delete
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6138
file_input_adapter(file_input_adapter &&) noexcept=default
Definition: json.hpp:6159
input_stream_adapter & operator=(input_stream_adapter &&)=delete
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6182
~input_stream_adapter()
Definition: json.hpp:6163
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6192
char char_type
Definition: json.hpp:6161
input_stream_adapter(const input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(std::istream &i)
Definition: json.hpp:6173
exception indicating errors with iterators
Definition: json.hpp:4457
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4460
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12837
~iter_impl()=default
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:13411
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:12974
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:13356
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:12964
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:13303
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:13338
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:13402
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13217
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:13511
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:13258
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13155
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13365
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13473
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12867
pointer operator->() const
dereference the iterator
Definition: json.hpp:13113
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:13536
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:13444
iter_impl(iter_impl &&) noexcept=default
std::bidirectional_iterator_tag iterator_category
The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
Definition: json.hpp:12862
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:13422
reference value() const
return the value of an iterator
Definition: json.hpp:13527
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:13347
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:12871
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13166
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12865
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13069
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13433
iter_impl()=default
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:12949
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:13294
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13206
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:12876
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:12939
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13030
Definition: json.hpp:5120
iteration_proxy_value operator++(int) &
Definition: json.hpp:5176
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5185
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5191
std::ptrdiff_t difference_type
Definition: json.hpp:5122
iteration_proxy_value(IteratorType it, std::size_t array_index_=0) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_default_constructible< string_type >::value)
Definition: json.hpp:5143
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5168
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5127
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5233
const string_type & key() const
return key of the iterator
Definition: json.hpp:5197
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
std::input_iterator_tag iterator_category
Definition: json.hpp:5126
proxy class for the items() function
Definition: json.hpp:5241
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5266
iteration_proxy(iteration_proxy const &)=default
iteration_proxy(iteration_proxy &&) noexcept=default
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5260
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5250
iteration_proxy & operator=(iteration_proxy const &)=default
Definition: json.hpp:6214
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:6222
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6218
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6216
Definition: json.hpp:14733
json_ref(json_ref &&) noexcept=default
json_ref(const value_type &value)
Definition: json.hpp:14741
json_ref(value_type &&value)
Definition: json.hpp:14737
value_type const & operator*() const
Definition: json.hpp:14772
value_type const * operator->() const
Definition: json.hpp:14777
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:14745
json_ref(Args &&... args)
Definition: json.hpp:14752
value_type moved_or_copied() const
Definition: json.hpp:14763
BasicJsonType value_type
Definition: json.hpp:14735
a template for a reverse iterator class
Definition: json.hpp:13590
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13606
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13618
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13612
std::ptrdiff_t difference_type
Definition: json.hpp:13592
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13630
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13654
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13660
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13648
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:13596
reference value() const
return the value of an iterator
Definition: json.hpp:13667
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13603
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13624
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:13594
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13642
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:13599
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13636
Definition: json.hpp:7226
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7229
bool end_object()
Definition: json.hpp:7279
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7269
bool binary(binary_t &)
Definition: json.hpp:7264
bool number_integer(number_integer_t)
Definition: json.hpp:7244
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7284
bool boolean(bool)
Definition: json.hpp:7239
bool null()
Definition: json.hpp:7234
bool end_array()
Definition: json.hpp:7289
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:7249
bool string(string_t &)
Definition: json.hpp:7259
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:7232
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:7254
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:7294
bool key(string_t &)
Definition: json.hpp:7274
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7228
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7230
typename BasicJsonType::string_t string_t
Definition: json.hpp:7231
Definition: json.hpp:6919
bool boolean(bool val)
Definition: json.hpp:6950
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:7107
typename BasicJsonType::string_t string_t
Definition: json.hpp:6924
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6968
constexpr bool is_errored() const
Definition: json.hpp:7119
bool string(string_t &val)
Definition: json.hpp:6974
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6922
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6925
bool start_object(std::size_t len)
Definition: json.hpp:6986
bool start_array(std::size_t len)
Definition: json.hpp:7057
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6921
bool end_array()
Definition: json.hpp:7074
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool key(string_t &val)
Definition: json.hpp:7004
bool end_object()
Definition: json.hpp:7021
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6927
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6926
bool null()
Definition: json.hpp:6944
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6962
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6929
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6923
bool number_integer(number_integer_t val)
Definition: json.hpp:6956
bool binary(binary_t &val)
Definition: json.hpp:6980
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6736
json_sax_dom_parser(const json_sax_dom_parser &)=delete
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool string(string_t &val)
Definition: json.hpp:6790
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6749
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6857
bool null()
Definition: json.hpp:6760
typename BasicJsonType::string_t string_t
Definition: json.hpp:6741
bool start_object(std::size_t len)
Definition: json.hpp:6802
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6739
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6778
bool number_integer(number_integer_t val)
Definition: json.hpp:6772
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6738
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool binary(binary_t &val)
Definition: json.hpp:6796
json_sax_dom_parser(json_sax_dom_parser &&)=default
bool boolean(bool val)
Definition: json.hpp:6766
bool end_array()
Definition: json.hpp:6846
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6784
bool end_object()
Definition: json.hpp:6824
constexpr bool is_errored() const
Definition: json.hpp:6869
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6742
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6740
bool start_array(std::size_t len)
Definition: json.hpp:6834
bool key(string_t &val)
Definition: json.hpp:6814
Definition: json.hpp:7341
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:7368
token_type
token types for the parser
Definition: json.hpp:7345
lexical analysis
Definition: json.hpp:7418
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8792
void skip_whitespace()
Definition: json.hpp:8806
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7429
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8779
std::string get_token_string() const
return the last read token (for errors only).
Definition: json.hpp:8754
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8718
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8746
token_type scan()
Definition: json.hpp:8814
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8724
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7427
lexer(lexer &&)=default
~lexer()=default
lexer & operator=(lexer &&)=default
lexer(const lexer &)=delete
lexer & operator=(lexer &)=delete
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8736
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8730
exception indicating other library errors
Definition: json.hpp:4509
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4512
exception indicating access out of the defined range
Definition: json.hpp:4492
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4495
Definition: json.hpp:14950
output_adapter(StringType &s)
Definition: json.hpp:14961
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:14957
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:14953
output adapter for output streams
Definition: json.hpp:14902
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14904
void write_character(CharType c) override
Definition: json.hpp:14908
output adapter for basic_string
Definition: json.hpp:14927
void write_character(CharType c) override
Definition: json.hpp:14933
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:14929
output adapter for byte vectors
Definition: json.hpp:14877
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14879
void write_character(CharType c) override
Definition: json.hpp:14883
exception indicating a parse error
Definition: json.hpp:4404
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.hpp:4416
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4424
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4441
syntax analysis
Definition: json.hpp:12162
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:12172
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12194
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12254
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:12262
Definition: json.hpp:12654
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12716
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12748
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12683
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12729
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12677
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12699
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12689
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12722
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12742
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12694
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12665
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12711
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12704
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12671
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12735
Definition: json.hpp:17973
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:18897
std::uint8_t state
Definition: json.hpp:18315
std::size_t bytes_after_last_accept
Definition: json.hpp:18319
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:17988
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.hpp:18313
std::size_t undumped_chars
Definition: json.hpp:18320
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:18892
const char decimal_point
the locale's decimal point character
Definition: json.hpp:18894
serializer & operator=(const serializer &)=delete
~serializer()=default
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18905
string_t indent_string
the indentation string
Definition: json.hpp:18902
const std::lconv * loc
the locale
Definition: json.hpp:18890
serializer & operator=(serializer &&)=delete
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:18887
const char indent_char
the indentation character
Definition: json.hpp:18900
std::size_t bytes
Definition: json.hpp:18316
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:18028
serializer(const serializer &)=delete
serializer(serializer &&)=delete
Definition: json.hpp:6540
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6548
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6555
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6558
exception indicating executing a member function with a wrong type
Definition: json.hpp:4475
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4478
Definition: json.hpp:6374
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6381
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6378
char char_type
Definition: json.hpp:6376
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:13754
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:13849
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13776
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:13856
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13780
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:13915
friend bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:14649
void pop_back()
remove last reference token
Definition: json.hpp:13877
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13786
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13834
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13908
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13816
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:13841
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13863
friend bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:14674
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13826
friend class json_pointer
Definition: json.hpp:13760
const string_t & back() const
return last reference token
Definition: json.hpp:13889
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition: json.hpp:13807
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13901
friend bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointer for less-than
Definition: json.hpp:14699
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5314
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2588
#define JSON_HEDLEY_CONST
Definition: json.hpp:1818
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1102
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2491
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1448
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2551
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:70
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1713
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1606
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2518
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:24378
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2047
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14649
#define JSON_CATCH(exception)
Definition: json.hpp:2517
#define JSON_ASSERT(x)
Definition: json.hpp:2544
#define JSON_THROW(exception)
Definition: json.hpp:2515
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:77
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:68
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2598
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1714
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12052
#define JSON_TRY
Definition: json.hpp:2516
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:144
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2497
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14674
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:69
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2773
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:134
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12049
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1103
#define JSON_EXPLICIT
Definition: json.hpp:2810
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1396
#define JSON_HEDLEY_PURE
Definition: json.hpp:1787
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14699
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:22800
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:17312
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:17148
Target reinterpret_bits(const Source source)
Definition: json.hpp:16868
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:17009
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:17366
constexpr int kAlpha
Definition: json.hpp:17131
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:17648
constexpr int kGamma
Definition: json.hpp:17132
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:17407
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:17748
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:17800
constexpr bool is_transparent()
Definition: json.hpp:4127
constexpr bool is_c_string()
Definition: json.hpp:4099
detail namespace with internal helper functions
Definition: json.hpp:249
input_format_t
the supported input formats
Definition: json.hpp:6108
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5714
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:309
typename make_void< Ts... >::type void_t
Definition: json.hpp:255
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9007
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14872
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4208
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:9015
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12153
OutStringType concat(Args &&... args)
Definition: json.hpp:4282
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4217
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3504
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3210
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3510
typename std::conditional< is_usable_as_key_type< typename BasicJsonType::object_comparator_t, typename BasicJsonType::object_t::key_type, KeyTypeCVRef, RequireTransparentComparator, ExcludeObjectKeyType >::value &&!is_json_iterator_of< BasicJsonType, KeyType >::value, std::true_type, std::false_type >::type is_usable_as_basic_json_key_type
Definition: json.hpp:3948
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:17885
typename T::pointer pointer_t
Definition: json.hpp:3495
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4202
parse_event_t
Definition: json.hpp:12136
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4211
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition: json.hpp:4944
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4755
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3171
typename T::value_type value_type_t
Definition: json.hpp:3489
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:313
T conditional_static_cast(U value)
Definition: json.hpp:3982
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4223
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3083
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8976
typename T::mapped_type mapped_type_t
Definition: json.hpp:3483
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2958
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8984
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3676
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5276
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9118
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:306
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3507
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6513
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3179
std::integral_constant< bool, Value > bool_constant
Definition: json.hpp:4089
void concat_into(OutStringType &)
Definition: json.hpp:4198
typename T::key_type key_type_t
Definition: json.hpp:3486
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4083
value_t
the JSON type enumeration
Definition: json.hpp:2860
@ null
null value
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.hpp:4005
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8992
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition: json.hpp:4838
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:300
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5956
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4214
typename T::iterator_category iterator_category_t
Definition: json.hpp:3501
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5938
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2889
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6456
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9010
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition: json.hpp:3960
error_handler_t
how to treat decoding errors
Definition: json.hpp:17965
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
std::size_t concat_length()
Definition: json.hpp:4167
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition: json.hpp:3679
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4598
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3583
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5576
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4612
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8968
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3187
typename T::difference_type difference_type_t
Definition: json.hpp:3492
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3069
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4938
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3918
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8988
typename std::conditional< std::is_same< T, void >::value, json_default_base, T >::type json_base_class
Definition: json.hpp:13708
typename T::reference reference_t
Definition: json.hpp:3498
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8972
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:9003
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:3951
typename T::key_compare detect_key_compare
Definition: json.hpp:3567
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8996
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4220
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8980
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:294
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2978
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:5113
std::integral_constant< bool,(std::is_signed< OfType >::value &&(sizeof(T)< sizeof(OfType)))||(same_sign< OfType, T >::value &&sizeof(OfType)==sizeof(T)) > never_out_of_range
Definition: json.hpp:4010
typename std::conditional< is_comparable< Comparator, ObjectKeyType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, ObjectKeyType >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, Comparator >::value) &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition: json.hpp:3932
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4205
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:9000
Definition: json.hpp:24384
Definition: json.hpp:5297
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24451
namespace for Niels Lohmann
Definition: json.hpp:5767
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:5791
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:5781
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:5771
Definition: json.hpp:3575
typename BasicJsonType::object_t object_t
Definition: json.hpp:3576
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3577
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3579
Definition: json.hpp:3590
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:6479
Definition: json.hpp:281
std::false_type value_t
Definition: json.hpp:282
Default type
Definition: json.hpp:283
Definition: json.hpp:16996
diyfp w
Definition: json.hpp:16997
diyfp minus
Definition: json.hpp:16998
diyfp plus
Definition: json.hpp:16999
Definition: json.hpp:17135
std::uint64_t f
Definition: json.hpp:17136
int e
Definition: json.hpp:17137
int k
Definition: json.hpp:17138
Definition: json.hpp:16878
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16902
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:16984
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:16967
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16890
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16884
static constexpr int kPrecision
Definition: json.hpp:16879
std::uint64_t f
Definition: json.hpp:16881
int e
Definition: json.hpp:16882
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5501
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5476
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5466
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5488
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5517
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5405
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5414
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5359
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5427
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5453
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5440
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5536
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5557
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5546
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5381
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5392
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5372
Definition: json.hpp:5353
Definition: json.hpp:5033
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:5035
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3529
Definition: json.hpp:3514
Definition: json.hpp:3570
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3544
Definition: json.hpp:3539
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3559
Definition: json.hpp:3554
Definition: json.hpp:4549
Definition: json.hpp:3111
T value_type
Definition: json.hpp:3112
static constexpr std::size_t size() noexcept
Definition: json.hpp:3113
an iterator value
Definition: json.hpp:12770
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12774
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12776
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:12772
Definition: json.hpp:3463
Definition: json.hpp:3450
Definition: json.hpp:4114
Definition: json.hpp:3909
Definition: json.hpp:3773
Definition: json.hpp:3792
Definition: json.hpp:3863
Definition: json.hpp:3713
Definition: json.hpp:3750
static constexpr auto value
Definition: json.hpp:3751
Definition: json.hpp:3866
Definition: json.hpp:3879
Definition: json.hpp:3686
Definition: json.hpp:3836
Definition: json.hpp:3746
Definition: json.hpp:3757
ConstructibleStringType laundered_type
Definition: json.hpp:3762
static constexpr auto value
Definition: json.hpp:3765
Definition: json.hpp:3882
Definition: json.hpp:3623
Definition: json.hpp:3603
Definition: json.hpp:297
Definition: json.hpp:3522
static constexpr bool value
Definition: json.hpp:3523
Definition: json.hpp:6432
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6433
Definition: json.hpp:3639
Definition: json.hpp:3888
Definition: json.hpp:3473
Definition: json.hpp:3970
char x[2]
Definition: json.hpp:3971
Definition: json.hpp:3966
static one test(decltype(&C::capacity))
@ value
Definition: json.hpp:3977
char one
Definition: json.hpp:3967
static two test(...)
Definition: json.hpp:3658
static constexpr bool value
Definition: json.hpp:3672
Definition: json.hpp:9050
Definition: json.hpp:9019
static constexpr bool value
Definition: json.hpp:9032
Definition: json.hpp:3899
Definition: json.hpp:4136
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6444
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6448
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6422
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6421
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6424
IteratorType iterator_type
Definition: json.hpp:6420
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3290
Definition: json.hpp:3278
Definition: json.hpp:3259
Default base class of the basic_json class.
Definition: json.hpp:13701
Definition: json.hpp:252
void type
Definition: json.hpp:253
Definition: json.hpp:3597
Definition: json.hpp:267
nonesuch(nonesuch const &&)=delete
~nonesuch()=delete
void operator=(nonesuch &&)=delete
void operator=(nonesuch const &)=delete
nonesuch(nonesuch const &)=delete
abstract output adapter interface
Definition: json.hpp:14858
output_adapter_protocol(const output_adapter_protocol &)=default
virtual ~output_adapter_protocol()=default
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
virtual void write_characters(const CharType *s, std::size_t length)=0
struct to capture the start position of the current token
Definition: json.hpp:3024
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3028
std::size_t lines_read
the number of lines read
Definition: json.hpp:3030
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3026
Definition: json.hpp:3194
Definition: json.hpp:3200
static JSON_INLINE_VARIABLE constexpr T value
Definition: json.hpp:3201
Definition: json.hpp:5734
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:5736
Definition: json.hpp:3131
Definition: json.hpp:3150
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3152
static constexpr bool test(T val)
Definition: json.hpp:4067
static constexpr bool test(T)
Definition: json.hpp:4076
Definition: json.hpp:4062
static constexpr bool test(T val)
Definition: json.hpp:4020
static constexpr bool test(T val)
Definition: json.hpp:4040
static constexpr bool test(T val)
Definition: json.hpp:4030
static constexpr bool test(T val)
Definition: json.hpp:4051
Definition: json.hpp:4015
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6313
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6255
Definition: json.hpp:6249
SAX interface.
Definition: json.hpp:6605
virtual bool binary(binary_t &val)=0
a binary value was read
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
virtual bool key(string_t &val)=0
an object key was read
json_sax()=default
virtual bool string(string_t &val)=0
a string value was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6606
typename BasicJsonType::string_t string_t
Definition: json.hpp:6609
virtual bool end_array()=0
the end of an array was read
json_sax(const json_sax &)=default
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6608
virtual bool null()=0
a null value was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6607
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6610
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
a minimal map-like container that preserves insertion order
Definition: json.hpp:18947
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:18950
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:19241
typename Container::value_type value_type
Definition: json.hpp:18954
std::equal_to< Key > key_compare
Definition: json.hpp:18958
iterator erase(iterator pos)
Definition: json.hpp:19119
T mapped_type
Definition: json.hpp:18949
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:18964
T & operator[](KeyType &&key)
Definition: json.hpp:19006
typename Container::iterator iterator
Definition: json.hpp:18951
const T & at(KeyType &&key) const
Definition: json.hpp:19066
T & at(KeyType &&key)
Definition: json.hpp:19038
const T & operator[](KeyType &&key) const
Definition: json.hpp:19018
iterator find(const key_type &key)
Definition: json.hpp:19203
iterator erase(iterator first, iterator last)
Definition: json.hpp:19124
const T & at(const key_type &key) const
Definition: json.hpp:19051
const_iterator find(const key_type &key) const
Definition: json.hpp:19229
T & operator[](const key_type &key)
Definition: json.hpp:18999
size_type erase(KeyType &&key)
Definition: json.hpp:19100
typename Container::size_type size_type
Definition: json.hpp:18953
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:18963
void insert(InputIt first, InputIt last)
Definition: json.hpp:19264
size_type count(const key_type &key) const
Definition: json.hpp:19177
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:18986
size_type erase(const key_type &key)
Definition: json.hpp:19079
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:18968
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:19246
size_type count(KeyType &&key) const
Definition: json.hpp:19191
Key key_type
Definition: json.hpp:18948
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:18966
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:19261
const T & operator[](const key_type &key) const
Definition: json.hpp:19011
iterator find(KeyType &&key)
Definition: json.hpp:19217
T & at(const key_type &key)
Definition: json.hpp:19023
typename Container::const_iterator const_iterator
Definition: json.hpp:18952
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:18971
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:24420
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:24434